shhh <- suppressPackageStartupMessages # It's a library, so shhh!

shhh(library( mgcv ))
shhh(library(dplyr))
shhh(library(ggplot2))
shhh(library(lme4))
shhh(library(tidymv))
shhh(library(gamlss))
shhh(library(gsubfn))
shhh(library(lmerTest))
shhh(library(tidyverse))
shhh(library(boot))
shhh(library(rsample))
shhh(library(plotrix))
shhh(library(ggrepel))
shhh(library(mgcv))

shhh(library(brms))
shhh(library(bayesplot))
shhh(library(patchwork))
shhh(library(MASS))
shhh(library(tidyr))
shhh(library(extraDistr))
shhh(library(purrr))
# For exercises with Stan code
shhh(library(rstan))
options(mc.cores = parallel::detectCores())
rstan_options(auto_write = FALSE)

shhh(library(car))
shhh(library(coda))
shhh(library(gridExtra))

theme_set(theme_bw())
options(digits=4)
options(scipen=999)
set.seed(444)
pipe_message = function(.data, status) {message(status); .data}

Read in MoTR Data


rate = 160

file_prefix = "../data/provo_f160/"
fnames = list.files(path=file_prefix)

df = data.frame()
for (f in fnames) {
  temp = read.csv(paste0(file_prefix, "/", f)) %>%
    mutate(subj = str_remove(f, "_reading_measures.csv"))
  df = rbind(df, temp)
}

# Filter out readers whose accuracy to the comprehension questions were less than 80%.
filter_df = df %>%
  group_by(para_nr, subj) %>% summarise(correct = if_else(unique(correctness) == 1, 1, 0)) %>% ungroup() %>%
  drop_na() %>%
  group_by(subj) %>% summarise(p_correct = mean(correct)) %>% ungroup() %>%
  mutate(p_correct = round(p_correct, digits = 2))
`summarise()` has grouped output by 'para_nr'. You can override using the `.groups` argument.
filter_df = filter_df %>% filter(p_correct < 0.8)
filter_list = filter_df$subj
pilot_exceptions <- c("reader_255", "reader_256", "reader_259", "reader_261", "reader_262", "reader_263")

raw_df = df %>%
  filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
  mutate(word = str_trim(word)) %>%
  mutate(subj = str_remove(subj, "reader_")) %>%
  mutate(subj = as.character(subj)) %>%
  mutate(FPReg = if_else(total_duration == 0, -1, FPReg)) %>% #If the word is skipped we can't say that it wasn't regressed on the first pass. Set to a "NA"
  dplyr::select(expr_id, cond_id, para_nr, word, word_nr, first_duration, total_duration, gaze_duration, go_past_time, FPReg, subj)
length(unique(raw_df$subj))
[1] 98
df %>%
  filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
  filter(FPReg >= 0) %>%
  dplyr::select(FPReg) %>%
  drop_na() %>%
  summarise( m = mean(FPReg))

df %>%
  filter(! subj %in% c(filter_list) | (subj %in% pilot_exceptions)) %>%
  dplyr::select(FPFix) %>%
  drop_na() %>%
  summarise( m = mean(FPFix))
NA
NA
# View(raw_df)
# Average across subjects
motr_agg_df = raw_df %>%
  gather(metric, value, 6:10) %>%
    filter(value >= 0) %>% #Removes the "NA" values for FPReg
  
    # ==== Remove skipped words
    # mutate(zero = if_else(metric != "FPReg" & value == 0,T, F)) %>%
    # filter(zero == F) %>%
  
    drop_na() %>%
    group_by(para_nr, word_nr, word, metric) %>%
    
    # === Remove outliers > 3SD
      # mutate(outlier = if_else(metric != "FPReg" & value > (mean(value) + 3 * sd(value)), T, F)) %>% filter(outlier == F) %>%
  
      summarise(value = mean(value), nsubj = length(unique(subj))) %>%
  ungroup() %>%
  arrange(para_nr, word_nr) %>%
  rename(text_id = para_nr, word_text_idx = word_nr, motr_value = value)
`summarise()` has grouped output by 'para_nr', 'word_nr', 'word'. You can override using the `.groups` argument.
# View(motr_agg_df)

Comparison to Provo

# Read in Provo surprisal, frequency and length data
provo_modeling_df = read.csv("../data/provo_stats.csv") %>%
  dplyr::select(text_id, sent_id, trigger_idx, word, freq, surp, len) %>%
  rename(word_idx = trigger_idx)

provo_modeling_df
NA
# Read in Provo eyetracking data

provo_raw_df = read.csv("../data/provo_eyetracking.csv")

# unique(provo_raw_df$Participant_ID)
# length(unique(provo_raw_df$Participant_ID))

provo_eyetracking_df = provo_raw_df %>%
  dplyr::select(Participant_ID, Text_ID, Sentence_Number, Word_In_Sentence_Number, Word, Word_Number, IA_FIRST_FIX_PROGRESSIVE, IA_FIRST_RUN_DWELL_TIME, IA_DWELL_TIME, IA_REGRESSION_PATH_DURATION, IA_REGRESSION_OUT, IA_SKIP) %>%
  rename( #first_duration = IA_FIRST_FIXATION_DURATION,   
          gaze_duration = IA_FIRST_RUN_DWELL_TIME,
          total_duration = IA_DWELL_TIME,
          go_past_time = IA_REGRESSION_PATH_DURATION,
          subj = Participant_ID,
          text_id = Text_ID,
          sent_id = Sentence_Number,
          word_idx = Word_In_Sentence_Number,
          word_text_idx = Word_Number,   # IA_ID?
          word = Word,      # Word?
          FPReg = IA_REGRESSION_OUT,
          skip = IA_SKIP,
          ff_progressive = IA_FIRST_FIX_PROGRESSIVE) %>%
  mutate(first_duration = gaze_duration) %>%
  mutate(gaze_duration = if_else(ff_progressive == 0, 0, as.double(gaze_duration)),
         go_past_time = if_else(ff_progressive == 0, 0, as.double(go_past_time))) %>%
  dplyr::select(-ff_progressive) %>%
  
  mutate(
    gaze_duration = if_else(total_duration == 0, 0, as.double(gaze_duration)),
      go_past_time = if_else(total_duration == 0, 0, as.double(go_past_time)),
      FPReg = if_else(total_duration == 0, -1, as.double(FPReg)),
      first_duration =  if_else(total_duration == 0, 0, as.double(first_duration)),
  ) %>%
  gather(metric, value, 7:12) %>%
  filter(value >= 0) %>%          # filter skipped word in eye tracking data for FPReg
  
  # ==== Remove skipped words
  # mutate(zero = if_else(metric != "FPReg" & value == 0,T, F)) %>%
  # filter(zero == F) %>%
  
  # mutate(value = if_else(is.na(value), as.integer(0), as.integer(value))) %>%
  # mutate(value = if_else(metric != "FPReg" & is.na(value), as.integer(0), as.integer(value))) %>%
  drop_na() %>%
  mutate(word = str_trim(word)) %>%
  mutate(subj = str_remove(subj, "Sub")) %>%
  mutate(subj = as.integer(subj)) %>%
    group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
  
  # === Remove outliers > 3SD
    # mutate(outlier = if_else(! metric %in% c("FPReg", "skip") & value > (mean(value) + 3 * sd(value) ), T, F)) %>%
    # filter(outlier == F) %>%
  
  ungroup() #%>%

# Aggregate cross-participant data for all subjects
provo_eyetracking_agg_df = provo_eyetracking_df %>%
  group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
    summarise(value = mean(value),
              nsubj = length(unique(subj))) %>%
    ungroup()
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
provo_raw_df %>%
  dplyr::select(IA_REGRESSION_OUT) %>%
  drop_na() %>%
  summarise( m = mean(IA_REGRESSION_OUT))

provo_raw_df %>%
  dplyr::select(IA_SKIP) %>%
  drop_na() %>%
  summarise( m = mean(IA_SKIP))
NA

# Split the eyetracking data in two by subjects to see how well it correlates with itself
provo_eyetracking_subj1_df_temp = provo_eyetracking_df %>%
  filter(subj <= 42) %>%
  mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
  group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
    summarise(value = mean(value)) %>%
  ungroup() %>%
  rename(value_1 = value) #%>%
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
  # dplyr::select(-sent_id, -word_idx)


provo_eyetracking_subj1_df = merge(provo_eyetracking_subj1_df_temp, motr_agg_df, by=c("text_id", "word_text_idx", "metric")) %>%
  arrange(text_id, sent_id, word_idx) %>%
  filter(!(text_id == 13 & word_text_idx >= 20 & word_text_idx <= 52)) %>%
  filter(!(text_id == 3 & word_text_idx >= 46 & word_text_idx <= 57)) %>%
  rename(word = word.y) %>%
  dplyr::select(text_id, word_text_idx, metric, word, value_1) 

# View(provo_eyetracking_subj1_df)

provo_eyetracking_subj2_df = provo_eyetracking_df %>%
  filter(subj > 42) %>%
  mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
  group_by(text_id, word_text_idx, sent_id, word_idx, word, metric) %>%
    summarise(value = mean(value)) %>%
  ungroup() %>%
    rename(value_2 = value)%>%
  dplyr::select(-sent_id, -word_idx)
`summarise()` has grouped output by 'text_id', 'word_text_idx', 'sent_id', 'word_idx', 'word'. You can override using the `.groups` argument.
# View(provo_eyetracking_subj2_df)
  
provo_eyetr_grouped_df = merge(provo_eyetracking_subj2_df, provo_eyetracking_subj1_df, by=c("text_id", "word_text_idx", "metric")) %>%
  # filter(word.x == word.y) %>%
  dplyr::select(-word.y) %>%
  # === Remove outliers > 3SD
  # group_by(metric) %>%
  #   mutate(motr_outlier = if_else(! metric %in% c("FPReg", "skip") & value_1 > (mean(value_1) + 3 * sd(value_1) ), T, F)) %>%
  #   filter(motr_outlier == F) %>%
  #   mutate(eyetr_outlier = if_else(! metric %in% c("FPReg", "skip") & value_2 > (mean(value_2) + 3 * sd(value_2) ), T, F)) %>%
  #   filter(eyetr_outlier == F) %>%
  # ungroup() %>%
  
  gather(measure, value, c("value_1", "value_2")) #%>%
  # dplyr::select(-motr_outlier, -eyetr_outlier)

# View(provo_eyetr_grouped_df)
provo_df = merge(provo_eyetracking_agg_df, provo_modeling_df, by=c("text_id", "sent_id", "word_idx")) %>%
  mutate(word_text_idx = as.integer(word_text_idx - 1)) %>%
  arrange(text_id, sent_id, word_idx) %>%
  rename(eyetr_value = value) 

provo_df = merge(provo_df, motr_agg_df, by=c("text_id", "word_text_idx", "metric")) %>%
arrange(text_id, sent_id, word_idx) %>%
  # almost all the word.x != word.y is because of normalization problem, so we can keep them, instead, deleting some special cases
filter(!(text_id == 13 & word_text_idx >= 20 & word_text_idx <= 52)) %>%
  filter(!(text_id == 3 & word_text_idx >= 46 & word_text_idx <= 57)) %>%
# filter(word.x == word) #%>%
dplyr::select(-word.x, -word.y) %>%
  
# === Remove outliers > 3SD
# group_by(metric) %>%
#   mutate(motr_outlier = if_else(! metric %in% c("FPReg", "skip") & motr_value > (mean(motr_value) + 3 * sd(motr_value) ), T, F)) %>%
#   filter(motr_outlier == F) %>%
#   mutate(eyetr_outlier = if_else(! metric %in% c("FPReg", "skip") & eyetr_value > (mean(eyetr_value) + 3 * sd(eyetr_value) ), T, F)) %>%
#   filter(eyetr_outlier == F) %>%
# ungroup() %>%
  
gather(measure, value, c("eyetr_value", "motr_value")) #%>%
# dplyr::select(-motr_outlier, -eyetr_outlier)
  
# provo_df

Bayesian – use Stan – motr & eyetr correlation

print("Gaze Duration")
[1] "Gaze Duration"
gd_df = provo_df %>% filter(metric == "gaze_duration") %>% 
  spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value =  pmax(eyetr_value, 1),
         motr_value = pmax(motr_value, 1)
  ) %>%
  mutate(eyetr_value_log = log(eyetr_value),
         motr_value_log = log(motr_value))
print(cor.test(gd_df$eyetr_value, gd_df$motr_value)$estimate)
   cor 
0.8174 
print(cor.test(gd_df$eyetr_value_log, gd_df$motr_value_log)$estimate)
   cor 
0.7784 
# View(gd_df)
gd_df %>% 
  gather(measure, value, 12:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

NA
# center data around 0.

gd_temp <- gd_df[c("eyetr_value", "motr_value")] %>%
   # mutate(eyetr_value = eyetr_value - mean(eyetr_value),
   #      motr_value = motr_value - mean(motr_value)) %>%
  data.matrix()

gd_temp_log <- gd_df[c("eyetr_value_log", "motr_value_log")] %>%
 mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log), 
        motr_value_log = motr_value_log - mean(motr_value_log)) %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(gd_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")
# Plot the second data matrix gd_temp_log
plot(gd_temp_log, pch = 16, col = "red",
     main = "Centered Log-Transformed")

gd_data = list(x=gd_temp, N=nrow(gd_temp))

fit_gd = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=gd_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_gd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_gd, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds"))
print("Go Past Time")
[1] "Go Past Time"
gpt_df = provo_df %>% filter(metric == "go_past_time") %>% 
  spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value =  pmax(eyetr_value, 1),
         motr_value = pmax(motr_value, 1)
  ) %>%
  mutate(eyetr_value_log = log(eyetr_value),
         motr_value_log = log(motr_value))
print(cor.test(gpt_df$eyetr_value, gpt_df$motr_value)$estimate)
   cor 
0.7262 
print(cor.test(gpt_df$eyetr_value_log, gpt_df$motr_value_log)$estimate)
  cor 
0.724 
gpt_df %>% 
  gather(measure, value, 12:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

gpt_temp <- gpt_df[c("eyetr_value", "motr_value")] %>% data.matrix()

gpt_temp_log <- gpt_df[c("eyetr_value_log", "motr_value_log")] %>%
 mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log), 
        motr_value_log = motr_value_log - mean(motr_value_log)) %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gpt_temp
plot(gpt_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")
# Plot the second data matrix gpt_temp_log
plot(gpt_temp_log, pch = 16, col = "red",
     main = "Centered Log-Transformed")

# -------fit model go past time ----------
gpt_data = list(x=gpt_temp, N=nrow(gpt_temp))
fit_gpt = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=gpt_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_gpt@stanmodel@dso <- new("cxxdso")
saveRDS(fit_gpt, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds"))
print("Total Duration")
[1] "Total Duration"
td_df = provo_df %>% filter(metric == "total_duration") %>% 
  spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value =  pmax(eyetr_value, 1),
         motr_value = pmax(motr_value, 1)
  ) %>%
  mutate(eyetr_value_log = log(eyetr_value),
         motr_value_log = log(motr_value))
print(cor.test(td_df$eyetr_value, td_df$motr_value)$estimate)
   cor 
0.7982 
print(cor.test(td_df$eyetr_value_log, td_df$motr_value_log)$estimate)
   cor 
0.7752 
td_df %>% 
  gather(measure, value, 12:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

td_temp <- td_df[c("eyetr_value", "motr_value")] %>% data.matrix()

td_temp_log <- td_df[c("eyetr_value_log", "motr_value_log")] %>%
 mutate(eyetr_value_log = eyetr_value_log - mean(eyetr_value_log), 
        motr_value_log = motr_value_log - mean(motr_value_log)) %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(td_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")
# Plot the second data matrix td_temp_log
plot(td_temp_log, pch = 16, col = "red",
     main = "Centered Log-Transformed")

# -------fit model total duration ----------
td_data = list(x=td_temp, N=nrow(td_temp))
fit_td = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=td_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_td@stanmodel@dso <- new("cxxdso")
saveRDS(fit_td, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds"))
print("First Pass Regression Prob.")
[1] "First Pass Regression Prob."
reg_df = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5))
print(cor.test(reg_df$eyetr_value, reg_df$motr_value)$estimate)
   cor 
0.3929 
# View(reg_df)
reg_df %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp <- reg_df[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(reg_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

# -------fit model FPReg ----------
reg_data = list(x=reg_temp, N=nrow(reg_temp))
fit_reg = stan(
  file="stan_models/bivariate_normal_reg.stan", 
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_drop0s.rds"))

rank transformation for FPReg

reg_df = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  mutate(
    eyetr_value_rank = ifelse(eyetr_value > 0, rank(eyetr_value), NA),
    motr_value_rank = ifelse(motr_value > 0, rank(motr_value), NA)
  ) %>%
  drop_na()
#   mutate(
#   eyetr_value_rank = rank(eyetr_value, ties.method = "average"),
#   motr_value_rank = rank(motr_value, ties.method = "average")
# )
# View(reg_df)

print(cor.test(reg_df$eyetr_value_rank, reg_df$motr_value_rank)$estimate)
print(cor.test(reg_df$eyetr_value_rank, reg_df$motr_value_rank, method = "kendall"))


reg_df %>% 
  gather(measure, value, 14:15) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp <- reg_df[c("eyetr_value_rank", "motr_value_rank")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix td_temp
plot(reg_temp, pch = 16, col = "blue",
     main = "Rank Transformed")
# -------fit model FPReg RANK----------
reg_data = list(x=reg_temp, N=nrow(reg_temp))
fit_reg = stan(
  file="stan_models/bivariate_correlation_rank.stan", 
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_rank_drop0s.rds"))
fit_gd = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds")
fit_gpt = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds")
fit_td = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds")
fit_reg = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_drop0s.rds")
fit_reg_rank = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_rank_drop0s.rds")

# models for drop 0s
# fit_gd = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_gaze_duration_cor_drop0s.rds")
# fit_gpt = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_go_past_time_cor_drop0s.rds")
# fit_td = readRDS("./bayesian_models/bayesian_models_correlation/motr_eyetr_total_duration_cor_drop0s.rds")
# fit_reg = readRDS("./bayesian_models/bayesian_models_correlation/ranked_motr_eyetr_FPReg_cor.rds")

print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
print(fit_gd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           234.30    0.01   0.90    232.53    233.69    234.29    234.91    236.06  6945    1
mu[2]           371.77    0.02   1.74    368.30    370.63    371.77    372.91    375.24  6640    1
sigma[1]         37.80    0.01   0.81     36.24     37.26     37.79     38.34     39.42  5283    1
sigma[2]         71.83    0.02   1.46     69.03     70.82     71.83     72.82     74.71  5227    1
nu                4.46    0.00   0.30      3.92      4.25      4.45      4.65      5.08  5469    1
rho               0.51    0.00   0.02      0.48      0.50      0.51      0.52      0.54  6947    1
cov[1,1]       1429.34    0.84  61.16   1313.63   1388.16   1427.81   1469.75   1553.95  5276    1
cov[1,2]       1391.14    1.15  78.47   1239.24   1339.15   1390.35   1441.79   1551.58  4667    1
cov[2,1]       1391.14    1.15  78.47   1239.24   1339.15   1390.35   1441.79   1551.58  4667    1
cov[2,2]       5161.37    2.91 210.40   4765.32   5015.23   5159.80   5302.57   5580.95  5231    1
x_rand[1]       235.01    0.55  49.34    138.86    206.52    234.61    262.42    336.83  8089    1
x_rand[2]       373.62    1.07  95.15    182.83    319.23    372.21    425.30    567.12  7980    1
attempt           0.00    0.00   0.05      0.00      0.00      0.00      0.00      0.00  8050    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -25082.82    0.03   1.80 -25087.41 -25083.73 -25082.46 -25081.52 -25080.40  3875    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:04:08 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
print(fit_gpt)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%      25%       50%       75%     97.5% n_eff Rhat
mu[1]           306.99    0.02   1.71    303.61    305.9    306.97    308.14    310.35  8255    1
mu[2]           425.10    0.03   2.96    419.39    423.0    425.10    427.11    430.79  8294    1
sigma[1]         67.11    0.02   1.47     64.27     66.1     67.10     68.10     70.03  7296    1
sigma[2]        116.24    0.03   2.64    111.16    114.5    116.21    118.01    121.46  7232    1
nu                2.26    0.00   0.09      2.08      2.2      2.26      2.32      2.45  7418    1
rho               0.42    0.00   0.02      0.38      0.4      0.42      0.43      0.45  8786    1
cov[1,1]       4505.28    2.31 197.26   4130.64   4369.6   4501.91   4637.37   4904.27  7307    1
cov[1,2]       3248.81    2.51 213.71   2842.87   3101.4   3244.96   3391.94   3668.78  7277    1
cov[2,1]       3248.81    2.51 213.71   2842.87   3101.4   3244.96   3391.94   3668.78  7277    1
cov[2,2]      13517.55    7.22 613.53  12357.23  13097.8  13505.59  13925.78  14752.13  7226    1
x_rand[1]       318.77    1.49 134.42    121.89    258.4    309.38    363.21    564.06  8092    1
x_rand[2]       451.19    3.26 294.27    111.69    344.8    430.62    522.20    876.86  8131    1
attempt           0.04    0.00   0.21      0.00      0.0      0.00      0.00      1.00  8093    1
max_attempts     10.00     NaN   0.00     10.00     10.0     10.00     10.00     10.00   NaN  NaN
lp__         -29010.67    0.03   1.76 -29015.10 -29011.6 -29010.35 -29009.40 -29008.25  3994    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:05:58 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
print(fit_td)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           266.87    0.02   1.28    264.39    266.01    266.86    267.75    269.33  5448    1
mu[2]           420.80    0.03   2.46    416.02    419.15    420.76    422.47    425.53  5573    1
sigma[1]         52.62    0.02   1.10     50.47     51.88     52.61     53.36     54.78  4500    1
sigma[2]        100.49    0.03   2.03     96.58     99.11    100.48    101.84    104.53  4579    1
nu                4.28    0.00   0.27      3.79      4.09      4.27      4.46      4.85  5361    1
rho               0.62    0.00   0.01      0.59      0.61      0.62      0.63      0.65  6752    1
cov[1,1]       2769.92    1.73 115.77   2547.56   2691.20   2768.16   2846.87   3000.64  4498    1
cov[1,2]       3278.82    2.57 164.70   2966.61   3164.38   3277.56   3386.73   3608.01  4100    1
cov[2,1]       3278.82    2.57 164.70   2966.61   3164.38   3277.56   3386.73   3608.01  4100    1
cov[2,2]      10102.99    6.04 408.74   9326.88   9822.79  10095.99  10371.05  10925.76  4584    1
x_rand[1]       268.11    0.79  69.98    127.37    228.67    268.19    306.65    407.71  7859    1
x_rand[2]       427.30    1.52 133.15    166.09    351.69    423.23    498.89    698.02  7666    1
attempt           0.01    0.00   0.09      0.00      0.00      0.00      0.00      0.00  8123    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -26591.96    0.03   1.74 -26596.19 -26592.83 -26591.63 -26590.69 -26589.56  3343    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:07:59 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.--------------------------------------------"
print(fit_reg)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.14    0.00 0.00    0.13    0.14    0.14    0.14    0.14  8022    1
mu[2]           0.09    0.00 0.00    0.08    0.08    0.09    0.09    0.09  8135    1
sigma[1]        0.08    0.00 0.00    0.08    0.08    0.08    0.08    0.09  7142    1
sigma[2]        0.05    0.00 0.00    0.04    0.05    0.05    0.05    0.05  7221    1
nu              2.78    0.00 0.18    2.46    2.65    2.77    2.89    3.14  7451    1
rho             0.21    0.00 0.03    0.16    0.19    0.21    0.23    0.27  9921    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  7143    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8463    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8463    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  7208    1
x_rand[1]       0.17    0.00 0.13    0.02    0.10    0.15    0.21    0.42  7885    1
x_rand[2]       0.10    0.00 0.07    0.01    0.06    0.09    0.12    0.25  7935    1
attempt         0.17    0.01 0.46    0.00    0.00    0.00    0.00    1.00  7711    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         4545.35    0.03 1.75 4541.07 4544.43 4545.68 4546.62 4547.74  3653    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:09:17 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob. RANK--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. RANK--------------------------------------------"
print(fit_reg_rank)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean       sd      2.5%       25%       50%      75%     97.5% n_eff Rhat
mu[1]          1374.90    0.18    18.98   1337.48   1362.16   1374.73   1387.9   1411.91 11231    1
mu[2]          1804.27    0.11    11.31   1782.23   1796.66   1804.43   1811.9   1826.26 10240    1
sigma[1]        696.99    0.12    12.87    672.39    688.36    696.94    705.4    723.03 10941    1
sigma[2]        418.96    0.08     7.84    403.87    413.54    418.83    424.2    434.92 10853    1
nu              102.55    0.23    23.98     63.02     85.64    100.14    116.5    157.44 10504    1
rho               0.19    0.00     0.03      0.14      0.17      0.19      0.2      0.24 11138    1
cov[1,1]     485954.71  172.11 17956.82 452113.94 473835.62 485723.58 497595.5 522770.76 10885    1
cov[1,2]      54509.75   75.79  7861.98  39206.85  49139.03  54379.02  59723.2  70306.93 10762    1
cov[2,1]      54509.75   75.79  7861.98  39206.85  49139.03  54379.02  59723.2  70306.93 10762    1
cov[2,2]     175589.65   63.18  6576.69 163113.47 171011.52 175420.06 179976.5 189159.61 10834    1
x_rand[1]      1420.17    7.48   659.95    217.73    942.20   1404.35   1864.0   2767.59  7778    1
x_rand[2]      1804.04    4.94   427.24    964.46   1521.76   1803.44   2090.0   2641.59  7493    1
attempt           0.03    0.00     0.18      0.00      0.00      0.00      0.0      1.00  8072    1
max_attempts     10.00     NaN     0.00     10.00     10.00     10.00     10.0     10.00   NaN  NaN
lp__         -20329.53    0.03     1.75 -20333.76 -20330.49 -20329.20 -20328.2 -20327.15  4066    1

Samples were drawn using NUTS(diag_e) at Tue Feb  6 00:12:53 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
# stan_trace(fit_gd, pars=c("rho", "mu", "sigma", "nu"))
# stan_dens(fit_gd, pars=c("rho", "mu", "sigma", "nu"), separate_chains = TRUE)
# stan_plot(fit_gd, pars=c("rho", "mu", "sigma", "nu"))

# Gaze Duration
stan_trace(fit_gd)
stan_dens(fit_gd, separate_chains = TRUE)
stan_plot(fit_gd)

# Go Past Time
stan_trace(fit_gpt)
stan_dens(fit_gpt, separate_chains = TRUE)
stan_plot(fit_gpt)

# Total Duration
stan_trace(fit_td)
stan_dens(fit_td, separate_chains = TRUE)
stan_plot(fit_td)

# FPReg
stan_trace(fit_reg)
stan_dens(fit_reg, separate_chains = TRUE)
stan_plot(fit_reg)
p1 <- stan_trace(fit_gd, pars = 'rho', inc_warmup = FALSE)
p2 <- stan_dens(fit_gd, pars = 'rho', separate_chains = TRUE)
p3 <- stan_trace(fit_gd, pars = 'mu[1]', inc_warmup = FALSE)
p4 <- stan_dens(fit_gd, pars = 'mu[1]', separate_chains = TRUE)
p5 <- stan_trace(fit_gd, pars = 'mu[2]', inc_warmup = FALSE)
p6 <- stan_dens(fit_gd, pars = 'mu[2]', separate_chains = TRUE)
p7 <- stan_trace(fit_gd, pars = 'sigma[1]', inc_warmup = FALSE)
p8 <- stan_dens(fit_gd, pars = 'sigma[1]', separate_chains = TRUE)
p9 <- stan_trace(fit_gd, pars = 'sigma[2]', inc_warmup = FALSE)
p10 <- stan_dens(fit_gd, pars = 'sigma[2]', separate_chains = TRUE)
p11 <- stan_trace(fit_gd, pars = 'nu', inc_warmup = FALSE)
p12 <- stan_dens(fit_gd, pars = 'nu', separate_chains = TRUE)


# Use grid.arrange() to arrange the plots
# grid.arrange(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, ncol=2, nrow=6)
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
rho_gd = as.numeric(extract(fit_gd, "rho")[[1]])
mean = mean(rho_gd)
crI = quantile(rho_gd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_gd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.5121
HPD: [0.4784, 0.5441]
crI: [0.4789, 0.5448]
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
rho_gpt = as.numeric(extract(fit_gpt, "rho")[[1]])
mean = mean(rho_gpt)
crI = quantile(rho_gpt, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_gpt), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.4163
HPD: [0.3793, 0.455]
crI: [0.378, 0.4539]
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
rho_td = as.numeric(extract(fit_td, "rho")[[1]])
mean = mean(rho_td)
crI = quantile(rho_td, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_td), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6197
HPD: [0.5915, 0.6471]
crI: [0.5912, 0.647]
print('---------------------------- First Pass Regression --------------------------------------------')
[1] "---------------------------- First Pass Regression --------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_reg = as.numeric(extract(fit_reg, "rho")[[1]])
mean = mean(rho_reg)
crI = quantile(rho_reg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_reg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.2139
HPD: [0.1561, 0.2715]
crI: [0.1554, 0.2711]
print('---------------------------- First Pass Regression RANK--------------------------------------------')
[1] "---------------------------- First Pass Regression RANK--------------------------------------------"
# rho_reg = as.numeric(extract(fit_reg, "rho[1, 2]")[[1]])
rho_reg = as.numeric(extract(fit_reg_rank, "rho")[[1]])
mean = mean(rho_reg)
crI = quantile(rho_reg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_reg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
Mean: 0.1866
HPD: [0.1359, 0.2356]
crI: [0.1367, 0.2367]
print('---------------------------- Gaze Duration--------------------------------------------')
gd_rand <- extract(fit_gd, "x_rand")[[1]]
# x_rand_filtered <- x_rand[apply(x_rand, 1, function(x) all(x > 0)),]
# x_rand_filtered

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 400), ylim=c(0, 700), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(gd_rand[,1], gd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(gd_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(gd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(gd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Go Past Time--------------------------------------------')
gpt_rand <- extract(fit_gpt, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Go Past Time") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(gpt_rand[,1], gpt_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(gpt_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(gpt_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(gpt_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Total Duration--------------------------------------------')
td_rand <- extract(fit_td, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "Total Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(td_rand[,1], td_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(td_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(td_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(td_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression --------------------------------------------')
reg_rand <- extract(fit_reg, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(reg_rand[,1], reg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(reg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(reg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

model motr eyetr FPReg correlation (eyetr < 0.3)

print("First Pass Regression Prob. all and  < 0.3")
[1] "First Pass Regression Prob. all and  < 0.3"
reg_df_all = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  # filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5))

reg_df_low_drop0 = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value < 0.3)

reg_df_low = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  # filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value < 0.3)
  # mutate(eyetr_value = exp(eyetr_value),
         # motr_value = exp(motr_value)
         # )
# View(reg_df)

print(cor.test(reg_df_all$eyetr_value, reg_df_all$motr_value)$estimate)
   cor 
0.3047 
print(cor.test(reg_df_all$eyetr_value, reg_df_all$motr_value)$p.value)
[1] 0.000000000000000000000000000000000000000000000000000000123
print(cor.test(reg_df_low$eyetr_value, reg_df_low$motr_value)$estimate)
   cor 
0.1065 
print(cor.test(reg_df_low$eyetr_value, reg_df_low$motr_value)$p.value)
[1] 0.0000003928
print(cor.test(reg_df_low_drop0$eyetr_value, reg_df_low_drop0$motr_value)$estimate)
    cor 
0.09068 
print(cor.test(reg_df_low_drop0$eyetr_value, reg_df_low_drop0$motr_value)$p.value)
[1] 0.001411
# View(reg_df)
reg_df_low %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp_all <- reg_df_all[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_low <- reg_df_low[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_low_drop0 <- reg_df_low_drop0[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix td_temp
plot(reg_temp_low, pch = 16, col = "blue",
     main = "Not Log-Transformed")

# -------fit model FPReg < 0.3 ----------
reg_data = list(x=reg_temp_all, N=nrow(reg_temp_all))
fit_reg = stan(
  # file="stan_models/bivariate_beta_correlation_reg.stan", 
  file = "stan_models/bivariate_normal_reg.stan",
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_all_data_drop0s.rds"))

model motr eyetr FPReg correlation (eyetr >= 0.3)

print("First Pass Regression Prob. >= 0.3")
[1] "First Pass Regression Prob. >= 0.3"
reg_df_high_drop0 = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value >= 0.3)

reg_df_high = provo_df %>% filter(metric == "FPReg") %>% 
  spread(measure, value) %>%
  # filter(eyetr_value > 0, motr_value > 0) %>%
  mutate(eyetr_value =  pmax(eyetr_value, 1e-5),
         motr_value = pmax(motr_value, 1e-5)) %>%
  filter(eyetr_value >= 0.3)
  # mutate(eyetr_value = exp(eyetr_value),
         # motr_value = exp(motr_value)
         # )
# View(reg_df)

print(cor.test(reg_df_high$eyetr_value, reg_df_high$motr_value)$estimate)
   cor 
0.4199 
print(cor.test(reg_df_high$eyetr_value, reg_df_high$motr_value)$p.value)
[1] 0.0000000000002953
print(cor.test(reg_df_high_drop0$eyetr_value, reg_df_high_drop0$motr_value)$estimate)
   cor 
0.4889 
print(cor.test(reg_df_high_drop0$eyetr_value, reg_df_high_drop0$motr_value)$p.value)
[1] 0.000000000001436
# View(reg_df)
reg_df_high %>% 
  gather(measure, value, 12:13) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

reg_temp_high <- reg_df_high[c("eyetr_value", "motr_value")] %>% data.matrix()
reg_temp_high_drop0 <- reg_df_high_drop0[c("eyetr_value", "motr_value")] %>% data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 3))

# Plot the first data matrix td_temp
plot(reg_temp_all, pch = 16, col = "blue",
     main = "FPReg not logged all data")
plot(reg_temp_low, pch = 16, col = "blue",
     main = "FPReg not logged eyetr < 0.3 ")
plot(reg_temp_high, pch = 16, col = "blue",
     main = "FPReg not logged eyetr >= 0.3")

# -------fit model FPReg >= 0.3 ----------
reg_data = list(x=reg_temp_high_drop0, N=nrow(reg_temp_high_drop0))
fit_reg = stan(
  # file="stan_models/bivariate_beta_correlation_reg.stan", 
  file = "stan_models/bivariate_normal_reg.stan",
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0(".//bayesian_models/bayesian_models_correlation/motr_eyetr_FPReg_cor_03-1_drop0s.rds"))
fit_mreg_all = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_all_data.rds")
fit_mreg_all_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_all_data_drop0s.rds")
fit_mreg_low = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_00-03.rds")
fit_mreg_low_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_00-03_drop0s.rds")
fit_mreg_high = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_03-1.rds")
fit_mreg_high_drop0 = readRDS("./bayesian_models/bayesian_models_correlation_2023/motr_eyetr_FPReg_cor_03-1_drop0s.rds")

print('---------------------------- First Pass Regression Prob. all data --------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. all data --------------------------------------------"
print(fit_mreg_all)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.12    0.00 0.00    0.12    0.12    0.12    0.13    0.13  5811    1
mu[2]           0.03    0.00 0.00    0.02    0.03    0.03    0.03    0.03  3384    1
sigma[1]        0.08    0.00 0.00    0.07    0.07    0.08    0.08    0.08  3694    1
sigma[2]        0.05    0.00 0.00    0.05    0.05    0.05    0.05    0.06  3040    1
nu              2.42    0.00 0.14    2.16    2.33    2.42    2.52    2.71  3250    1
rho             0.16    0.00 0.02    0.11    0.14    0.16    0.17    0.20  8176    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3693    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  6348    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  6348    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  3053    1
x_rand[1]       0.16    0.00 0.12    0.02    0.09    0.14    0.20    0.40  7811    1
x_rand[2]       0.07    0.00 0.08    0.00    0.03    0.05    0.09    0.25  7966    1
attempt         0.63    0.01 1.03    0.00    0.00    0.00    1.00    3.00  7919    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         7450.58    0.03 1.78 7446.22 7449.65 7450.92 7451.89 7452.98  3519    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 23:08:09 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob. all data no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob. all data no 0s--------------------------------------------"
print(fit_mreg_all_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.15    0.00 0.00    0.14    0.15    0.15    0.15    0.16  8507    1
mu[2]           0.14    0.00 0.00    0.13    0.14    0.14    0.14    0.14  7923    1
sigma[1]        0.09    0.00 0.00    0.08    0.08    0.09    0.09    0.09  7186    1
sigma[2]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.06  6227    1
nu              2.78    0.00 0.23    2.37    2.62    2.77    2.93    3.26  7008    1
rho             0.18    0.00 0.04    0.11    0.16    0.18    0.21    0.26  9833    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  7173    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8599    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8599    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  6234    1
x_rand[1]       0.18    0.00 0.13    0.02    0.10    0.16    0.22    0.43  7699    1
x_rand[2]       0.15    0.00 0.08    0.03    0.10    0.14    0.18    0.34  8175    1
attempt         0.16    0.00 0.43    0.00    0.00    0.00    0.00    1.00  7917    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         2566.44    0.03 1.75 2562.18 2565.53 2566.76 2567.72 2568.88  3487    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 23:18:11 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------"
print(fit_mreg_low)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.12    0.00 0.00    0.11    0.12    0.12    0.12    0.12  8566    1
mu[2]           0.03    0.00 0.00    0.03    0.03    0.03    0.04    0.04  4981    1
sigma[1]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.07  7280    1
sigma[2]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.07  4552    1
nu              5.54    0.01 0.51    4.62    5.19    5.51    5.86    6.62  4637    1
rho             0.10    0.00 0.02    0.06    0.09    0.10    0.12    0.15  8596    1
cov[1,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  7299    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8259    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8259    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  4571    1
x_rand[1]       0.13    0.00 0.07    0.02    0.08    0.12    0.17    0.28  8277    1
x_rand[2]       0.07    0.00 0.06    0.00    0.03    0.06    0.10    0.21  7280    1
attempt         0.53    0.01 0.90    0.00    0.00    0.00    1.00    3.00  8006    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         7794.82    0.03 1.78 7790.50 7793.88 7795.16 7796.13 7797.26  3232    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 20:52:03 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.< 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.< 0.3 no 0s--------------------------------------------"
print(fit_mreg_low_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.13    0.00 0.00    0.13    0.13    0.13    0.13    0.14 10534    1
mu[2]           0.13    0.00 0.00    0.13    0.13    0.13    0.14    0.14  8839    1
sigma[1]        0.06    0.00 0.00    0.06    0.06    0.06    0.06    0.07  8534    1
sigma[2]        0.06    0.00 0.00    0.06    0.06    0.06    0.07    0.07  7122    1
nu              6.50    0.01 0.96    4.90    5.83    6.40    7.06    8.73  6790    1
rho             0.07    0.00 0.04    0.00    0.05    0.07    0.10    0.15 10356    1
cov[1,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  8526    1
cov[1,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00 10435    1
cov[2,1]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00 10435    1
cov[2,2]        0.00    0.00 0.00    0.00    0.00    0.00    0.00    0.00  7123    1
x_rand[1]       0.14    0.00 0.07    0.02    0.09    0.13    0.18    0.28  8031    1
x_rand[2]       0.14    0.00 0.07    0.02    0.10    0.14    0.18    0.29  8006    1
attempt         0.08    0.00 0.30    0.00    0.00    0.00    0.00    1.00  7642    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         2737.21    0.03 1.76 2732.81 2736.27 2737.56 2738.50 2739.62  3992    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 20:30:02 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------"
print(fit_mreg_high)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

               mean se_mean    sd   2.5%    25%    50%    75%  97.5% n_eff Rhat
mu[1]          0.45    0.00  0.01   0.44   0.45   0.45   0.46   0.47  5045    1
mu[2]          0.15    0.00  0.01   0.13   0.15   0.15   0.16   0.18  4628    1
sigma[1]       0.11    0.00  0.01   0.10   0.11   0.11   0.12   0.12  5622    1
sigma[2]       0.15    0.00  0.01   0.13   0.15   0.15   0.16   0.17  4499    1
nu            25.71    0.18 12.83   9.59  16.53  22.89  31.70  58.03  5109    1
rho            0.41    0.00  0.06   0.30   0.37   0.41   0.45   0.51  7137    1
cov[1,1]       0.01    0.00  0.00   0.01   0.01   0.01   0.01   0.02  5625    1
cov[1,2]       0.01    0.00  0.00   0.00   0.01   0.01   0.01   0.01  4842    1
cov[2,1]       0.01    0.00  0.00   0.00   0.01   0.01   0.01   0.01  4842    1
cov[2,2]       0.02    0.00  0.00   0.02   0.02   0.02   0.03   0.03  4553    1
x_rand[1]      0.47    0.00  0.11   0.25   0.39   0.47   0.54   0.70  7964    1
x_rand[2]      0.20    0.00  0.13   0.01   0.10   0.19   0.28   0.49  7829    1
attempt        0.19    0.01  0.47   0.00   0.00   0.00   0.00   1.00  7881    1
max_attempts  10.00     NaN  0.00  10.00  10.00  10.00  10.00  10.00   NaN  NaN
lp__         579.26    0.03  1.75 575.10 578.35 579.56 580.56 581.68  3529    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 22:25:38 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.>= 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.>= 0.3 no 0s--------------------------------------------"
print(fit_mreg_high_drop0)
Inference for Stan model: bivariate_normal_reg.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

               mean se_mean    sd   2.5%    25%    50%    75%  97.5% n_eff Rhat
mu[1]          0.48    0.00  0.01   0.46   0.48   0.48   0.49   0.51  6409    1
mu[2]          0.27    0.00  0.01   0.25   0.26   0.27   0.28   0.30  6397    1
sigma[1]       0.12    0.00  0.01   0.11   0.12   0.12   0.13   0.14  6555    1
sigma[2]       0.16    0.00  0.01   0.14   0.15   0.16   0.17   0.18  6281    1
nu            32.85    0.16 15.27  11.84  21.65  30.12  40.80  69.54  8953    1
rho            0.51    0.00  0.07   0.37   0.47   0.52   0.56   0.64  6986    1
cov[1,1]       0.02    0.00  0.00   0.01   0.01   0.02   0.02   0.02  6491    1
cov[1,2]       0.01    0.00  0.00   0.01   0.01   0.01   0.01   0.02  5145    1
cov[2,1]       0.01    0.00  0.00   0.01   0.01   0.01   0.01   0.02  5145    1
cov[2,2]       0.03    0.00  0.00   0.02   0.02   0.03   0.03   0.03  6242    1
x_rand[1]      0.49    0.00  0.13   0.25   0.41   0.49   0.57   0.74  8129    1
x_rand[2]      0.29    0.00  0.15   0.04   0.18   0.28   0.38   0.60  7467    1
attempt        0.06    0.00  0.24   0.00   0.00   0.00   0.00   1.00  7913    1
max_attempts  10.00     NaN  0.00  10.00  10.00  10.00  10.00  10.00   NaN  NaN
lp__         300.28    0.03  1.75 296.05 299.35 300.60 301.58 302.70  3555    1

Samples were drawn using NUTS(diag_e) at Sat Aug  5 22:31:08 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
# # FPReg all data
# stan_trace(fit_mreg_all)
# stan_dens(fit_mreg_all, separate_chains = TRUE)
# stan_plot(fit_mreg_all)

# stan_trace(fit_mreg_all_drop0)
# stan_dens(fit_mreg_all_drop0, separate_chains = TRUE)
# stan_plot(fit_mreg_all_drop0)

# # FPReg < 0.3
# stan_trace(fit_mreg_low)
# stan_dens(fit_mreg_low, separate_chains = TRUE)
# stan_plot(fit_mreg_low)
# 
# stan_trace(fit_mreg_low_drop0)
# stan_dens(fit_mreg_low_drop0, separate_chains = TRUE)
# stan_plot(fit_mreg_low_drop0)

# FPReg > 0.3
stan_trace(fit_mreg_high)
'pars' not specified. Showing first 10 parameters by default.

stan_dens(fit_mreg_high, separate_chains = TRUE)
'pars' not specified. Showing first 10 parameters by default.

stan_plot(fit_mreg_high)
'pars' not specified. Showing first 10 parameters by default.
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

stan_trace(fit_mreg_high_drop0)
'pars' not specified. Showing first 10 parameters by default.

stan_dens(fit_mreg_high_drop0, separate_chains = TRUE)
'pars' not specified. Showing first 10 parameters by default.

stan_plot(fit_mreg_high_drop0)
'pars' not specified. Showing first 10 parameters by default.
ci_level: 0.8 (80% intervals)
outer_level: 0.95 (95% intervals)

print('---------------------------- First Pass Regression all data--------------------------------------------')
[1] "---------------------------- First Pass Regression all data--------------------------------------------"
rho_mreg_all = as.numeric(extract(fit_mreg_all, "rho")[[1]])
mean = mean(rho_mreg_all)
crI = quantile(rho_mreg_all, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_all), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.1574
HPD: [0.1139, 0.2017]
crI: [0.1134, 0.2014]
print('---------------------------- First Pass Regression all data no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression all data no 0s--------------------------------------------"
rho_mreg_all_drop0 = as.numeric(extract(fit_mreg_all_drop0, "rho")[[1]])
mean = mean(rho_mreg_all_drop0)
crI = quantile(rho_mreg_all_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_all_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.1843
HPD: [0.1106, 0.2573]
crI: [0.1114, 0.2581]
print('---------------------------- First Pass Regression < 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression < 0.3--------------------------------------------"
rho_mreg_low = as.numeric(extract(fit_mreg_low, "rho")[[1]])
mean = mean(rho_mreg_low)
crI = quantile(rho_mreg_low, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_low), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.103
HPD: [0.05775, 0.1468]
crI: [0.05805, 0.1475]
print('---------------------------- First Pass Regression < 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression < 0.3 no 0s--------------------------------------------"
rho_mreg_low_drop0 = as.numeric(extract(fit_mreg_low_drop0, "rho")[[1]])
mean = mean(rho_mreg_low_drop0)
crI = quantile(rho_mreg_low_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_low_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.07362
HPD: [-0.000616, 0.1514]
crI: [-0.003759, 0.1491]
print('---------------------------- First Pass Regression >= 0.3--------------------------------------------')
[1] "---------------------------- First Pass Regression >= 0.3--------------------------------------------"
rho_mreg_high = as.numeric(extract(fit_mreg_high, "rho")[[1]])
mean = mean(rho_mreg_high)
crI = quantile(rho_mreg_high, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_high), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.4102
HPD: [0.3001, 0.5155]
crI: [0.2992, 0.5146]
print('---------------------------- First Pass Regression >= 0.3 no 0s--------------------------------------------')
[1] "---------------------------- First Pass Regression >= 0.3 no 0s--------------------------------------------"
rho_mreg_high_drop0 = as.numeric(extract(fit_mreg_high_drop0, "rho")[[1]])
mean = mean(rho_mreg_high_drop0)
crI = quantile(rho_mreg_high_drop0, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mreg_high_drop0), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.514
HPD: [0.3797, 0.6456]
crI: [0.3728, 0.6412]
print('---------------------------- First Pass Regression all data --------------------------------------------')
mallreg_rand <- extract(fit_mreg_all, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mallreg_rand[,1], mallreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_all, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mallreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mallreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression all data no 0s--------------------------------------------')
mallreg_rand_drop0 <- extract(fit_mreg_all_drop0, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mallreg_rand_drop0[,1], mallreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_all, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mallreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mallreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression < 0.3 --------------------------------------------')
mlowreg_rand <- extract(fit_mreg_low, "x_rand")[[1]]
print(mlowreg_rand)
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mlowreg_rand[,1], mlowreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_low, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mlowreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlowreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression < 0.3 no 0s --------------------------------------------')
mlowreg_rand_drop0 <- extract(fit_mreg_low_drop0, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mlowreg_rand_drop0[,1], mlowreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_low_drop0, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mlowreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlowreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression >= 0.3 --------------------------------------------')
mhighreg_rand_samples <- extract(fit_mreg_high, "x_rand")[[1]]
# print(mhighreg_rand_samples)
selected_indices <- sample(1:nrow(mhighreg_rand_samples), 900)
mhighreg_rand <- mhighreg_rand_samples[selected_indices, ]
# mhighreg_rand <- extract(fit_mreg_high, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mhighreg_rand[,1], mhighreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_high, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mhighreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mhighreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

# print('---------------------------- First Pass Regression >= 0.3 no 0s --------------------------------------------')
mhighreg_rand_drop0_samples <- extract(fit_mreg_high_drop0, "x_rand")[[1]]
selected_indices <- sample(1:nrow(mhighreg_rand_drop0_samples), 900)
mhighreg_rand_drop0 <- mhighreg_rand_drop0_samples[selected_indices, ]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color
points(mhighreg_rand_drop0[,1], mhighreg_rand_drop0[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(reg_temp_high_drop0, pch=16, col="red")

# add dataEllipse with color
dataEllipse(mhighreg_rand_drop0, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mhighreg_rand_drop0, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

model eye tracking to eye tracking correlation


print("Gaze Duration")
[1] "Gaze Duration"
# View(provo_eyetr_grouped_df)

egd_df = provo_eyetr_grouped_df %>% filter(metric == "gaze_duration") %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
    filter(text_id != 18) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1),
         eyetr_value_2 = pmax(value_2, 1)
  ) 
print(cor.test(egd_df$eyetr_value_1, egd_df$eyetr_value_2)$estimate)
   cor 
0.9093 
# View(egd_df)

egd_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

egd_temp <- egd_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(egd_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

egd_data = list(x=egd_temp, N=nrow(egd_temp))

fit_egd = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=egd_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_egd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_egd, file = paste0("./bayesian_models/bayesian_models_correlation/cor_bivariate/eyetr_eyetr_gaze_duration_cor.rds"))
print("Go Past Time")
[1] "Go Past Time"
egpt_df = provo_eyetr_grouped_df %>% filter(metric == "go_past_time") %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
  filter(text_id != 18) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1),
         eyetr_value_2 = pmax(value_2, 1)
  ) 
print(cor.test(egpt_df$eyetr_value_1, egpt_df$eyetr_value_2)$estimate)
   cor 
0.8481 
# View(egd_df)

egpt_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

egpt_temp <- egpt_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(egpt_temp, pch = 16, col = "blue",
     main = "Not Log-Transformed")

egpt_data = list(x=egpt_temp, N=nrow(egpt_temp))

fit_egpt = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=egpt_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_egpt@stanmodel@dso <- new("cxxdso")
saveRDS(fit_egpt, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_go_past_time_cor.rds"))
print("Total Duration")
[1] "Total Duration"
etd_df = provo_eyetr_grouped_df %>% filter(metric == "total_duration") %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value, na.rm = TRUE), .groups = 'drop') %>%
  filter(text_id != 18) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1),
         eyetr_value_2 = pmax(value_2, 1)
  ) 
print(cor.test(etd_df$eyetr_value_1, etd_df$eyetr_value_2)$estimate)
   cor 
0.9205 
# View(egd_df)

etd_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

etd_temp <- etd_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(etd_temp, pch = 16, col = "blue",
     main = "Total Duration Not Log-Transformed")

etd_data = list(x=etd_temp, N=nrow(etd_temp))

fit_etd = stan(
  file="stan_models/bivariate_correlation.stan", 
  data=etd_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_etd@stanmodel@dso <- new("cxxdso")
saveRDS(fit_etd, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_total_duration_cor.rds"))
print("Fisrt Pass Regression Prob.")
[1] "Fisrt Pass Regression Prob."
ereg_df = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  # filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
  filter(text_id != 18) %>%
    spread(measure, value) %>%
  
  # ==== for normal data drop0s ====
  # filter(value_1 > 0, value_2 > 0) %>%
  # mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
  #        eyetr_value_2 = pmax(value_2, 1e-5)
  # )
  
  # ==== for ranking the data drop0s ====
    mutate(
    eyetr_value_1 = ifelse(value_1 > 0, rank(value_1), NA),
    eyetr_value_2 = ifelse(value_2 > 0, rank(value_2), NA)
  ) %>%
  drop_na()

  # ==== for ranking the data w/ 0s ====
  #   mutate(
  #   eyetr_value_1 = rank(value_1, ties.method = "average"),
  #   eyetr_value_2 = rank(value_2, ties.method = "average")
  # )


print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$estimate)
   cor 
0.5809 
# View(egd_df)

ereg_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

ereg_temp <- ereg_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))

# Plot the first data matrix gd_temp
plot(ereg_temp, pch = 16, col = "blue",
     main = "FPReg Not Log-Transformed")

# -------fit model FPReg ----------

# View(ereg_temp)
ereg_data = list(x=ereg_temp, N=nrow(ereg_temp))
fit_ereg = stan(
  file="stan_models/bivariate_correlation_rank.stan", 
  data=ereg_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99),
  verbose = FALSE
  )

# Save the model 
fit_ereg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_ereg, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_rank_drop0s.rds"))
fit_egd = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_gaze_duration_cor_drop0s.rds")
fit_egpt = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_go_past_time_cor_drop0s.rds")
fit_etd = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_total_duration_cor_drop0s.rds")
fit_ereg = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor.rds")
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
print(fit_egd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean    sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           234.21    0.01  1.00    232.27    233.54    234.19    234.87    236.20  4635    1
mu[2]           236.90    0.01  0.97    235.02    236.24    236.90    237.54    238.79  4910    1
sigma[1]         41.69    0.02  0.91     39.91     41.08     41.68     42.29     43.51  3619    1
sigma[2]         40.43    0.01  0.85     38.80     39.85     40.42     41.00     42.11  3582    1
nu                4.79    0.01  0.34      4.18      4.55      4.77      5.01      5.49  4490    1
rho               0.75    0.00  0.01      0.73      0.74      0.75      0.75      0.77  5064    1
cov[1,1]       1738.83    1.26 75.69   1593.04   1687.35   1737.16   1788.84   1892.83  3618    1
cov[1,2]       1261.40    1.07 60.61   1144.60   1219.78   1259.97   1301.33   1383.64  3231    1
cov[2,1]       1261.40    1.07 60.61   1144.60   1219.78   1259.97   1301.33   1383.64  3231    1
cov[2,2]       1635.31    1.15 68.73   1505.18   1588.13   1633.89   1680.99   1772.85  3581    1
x_rand[1]       235.04    0.60 53.55    126.81    204.21    234.45    265.21    343.46  8071    1
x_rand[2]       238.08    0.58 52.25    134.49    207.68    237.12    267.21    343.68  8199    1
attempt           0.00    0.00  0.06      0.00      0.00      0.00      0.00      0.00  7607    1
max_attempts     10.00     NaN  0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -22639.73    0.03  1.75 -22644.12 -22640.68 -22639.40 -22638.44 -22637.35  3653    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 23:34:23 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
print(fit_egpt)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           303.70    0.03   2.02    299.63    302.37    303.70    305.04    307.61  6230    1
mu[2]           302.11    0.02   1.80    298.65    300.89    302.10    303.33    305.69  6262    1
sigma[1]         77.62    0.03   1.77     74.18     76.42     77.61     78.81     81.07  4594    1
sigma[2]         68.55    0.02   1.51     65.64     67.52     68.54     69.56     71.58  4950    1
nu                2.33    0.00   0.10      2.13      2.25      2.32      2.40      2.53  5695    1
rho               0.63    0.00   0.01      0.60      0.62      0.63      0.64      0.66  7305    1
cov[1,1]       6028.02    4.05 274.38   5502.89   5840.25   6022.79   6211.77   6572.65  4595    1
cov[1,2]       3372.29    2.65 178.45   3030.75   3248.64   3367.12   3492.40   3732.72  4544    1
cov[2,1]       3372.29    2.65 178.45   3030.75   3248.64   3367.12   3492.40   3732.72  4544    1
cov[2,2]       4701.89    2.95 207.63   4308.25   4559.35   4698.02   4838.38   5123.15  4963    1
x_rand[1]       316.81    1.63 144.61     99.38    247.09    305.30    366.85    597.63  7836    1
x_rand[2]       312.58    1.38 123.98    111.40    252.31    305.23    357.38    569.45  8117    1
attempt           0.03    0.00   0.18      0.00      0.00      0.00      0.00      1.00  7784    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -26967.65    0.03   1.74 -26971.89 -26968.58 -26967.31 -26966.37 -26965.23  3624    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 23:38:33 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
print(fit_etd)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                  mean se_mean     sd      2.5%       25%       50%       75%     97.5% n_eff Rhat
mu[1]           272.77    0.02   1.40    270.02    271.83    272.77    273.69    275.55  4475    1
mu[2]           267.14    0.02   1.28    264.64    266.26    267.12    268.00    269.68  4593    1
sigma[1]         60.01    0.02   1.28     57.55     59.15     60.00     60.86     62.53  3656    1
sigma[2]         54.94    0.02   1.12     52.79     54.18     54.92     55.70     57.19  3673    1
nu                5.27    0.01   0.38      4.58      5.01      5.25      5.51      6.05  4498    1
rho               0.81    0.00   0.01      0.79      0.80      0.81      0.81      0.82  4869    1
cov[1,1]       3603.09    2.54 153.48   3311.44   3498.40   3599.66   3703.53   3909.89  3659    1
cov[1,2]       2670.69    2.11 121.75   2440.79   2585.48   2667.90   2750.53   2920.02  3333    1
cov[2,1]       2670.69    2.11 121.75   2440.79   2585.48   2667.90   2750.53   2920.02  3333    1
cov[2,2]       3019.99    2.04 123.51   2787.14   2935.61   3016.10   3102.72   3271.26  3671    1
x_rand[1]       273.92    0.82  73.68    128.22    230.21    274.02    316.06    420.89  8061    1
x_rand[2]       269.13    0.75  67.33    133.79    228.98    268.90    307.33    404.88  8079    1
attempt           0.00    0.00   0.06      0.00      0.00      0.00      0.00      0.00  7660    1
max_attempts     10.00     NaN   0.00     10.00     10.00     10.00     10.00     10.00   NaN  NaN
lp__         -24232.17    0.03   1.77 -24236.45 -24233.10 -24231.82 -24230.89 -24229.77  3293    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 23:41:09 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
print('---------------------------- First Pass Regression Prob.--------------------------------------------')
[1] "---------------------------- First Pass Regression Prob.--------------------------------------------"
print(fit_ereg)
Inference for Stan model: anon_model.
4 chains, each with iter=4000; warmup=2000; thin=1; 
post-warmup draws per chain=2000, total post-warmup draws=8000.

                mean se_mean   sd    2.5%     25%     50%     75%   97.5% n_eff Rhat
mu[1]           0.12    0.00 0.00    0.12    0.12    0.12    0.13    0.13  4915    1
mu[2]           0.13    0.00 0.00    0.12    0.12    0.13    0.13    0.13  5058    1
sigma[1]        0.10    0.00 0.00    0.09    0.09    0.10    0.10    0.10  3600    1
sigma[2]        0.09    0.00 0.00    0.09    0.09    0.09    0.09    0.10  3854    1
nu              3.84    0.00 0.22    3.43    3.69    3.83    3.99    4.30  4433    1
rho             0.67    0.00 0.01    0.65    0.66    0.67    0.68    0.70  5339    1
cov[1,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3597    1
cov[1,2]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3356    1
cov[2,1]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3356    1
cov[2,2]        0.01    0.00 0.00    0.01    0.01    0.01    0.01    0.01  3847    1
x_rand[1]       0.16    0.00 0.11    0.02    0.09    0.15    0.21    0.41  7785    1
x_rand[2]       0.16    0.00 0.10    0.02    0.09    0.15    0.21    0.40  8078    1
attempt         0.23    0.01 0.53    0.00    0.00    0.00    0.00    2.00  8328    1
max_attempts   10.00     NaN 0.00   10.00   10.00   10.00   10.00   10.00   NaN  NaN
lp__         7379.08    0.03 1.74 7374.84 7378.15 7379.40 7380.38 7381.48  3314    1

Samples were drawn using NUTS(diag_e) at Mon Feb  5 21:48:17 2024.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).
# stan_trace(fit_egd, pars=c("rho", "mu", "sigma", "nu"))
# stan_dens(fit_egd, pars=c("rho", "mu", "sigma", "nu"), separate_chains = TRUE)
# stan_plot(fit_egd, pars=c("rho", "mu", "sigma", "nu"))

# Gaze Duration
stan_trace(fit_egd)
stan_dens(fit_egd, separate_chains = TRUE)
stan_plot(fit_egd)

# Go Past Time
stan_trace(fit_egpt)
stan_dens(fit_egpt, separate_chains = TRUE)
stan_plot(fit_egpt)

# Total Duration
stan_trace(fit_etd)
stan_dens(fit_etd, separate_chains = TRUE)
stan_plot(fit_etd)

# FPReg
stan_trace(fit_ereg)
stan_dens(fit_ereg, separate_chains = TRUE)
stan_plot(fit_ereg)
print('---------------------------- Gaze Duration--------------------------------------------')
[1] "---------------------------- Gaze Duration--------------------------------------------"
rho_egd = as.numeric(extract(fit_egd, "rho")[[1]])
mean = mean(rho_egd)
crI = quantile(rho_egd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_egd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.7479
HPD: [0.7278, 0.7669]
crI: [0.7278, 0.767]
print('---------------------------- Go Past Time--------------------------------------------')
[1] "---------------------------- Go Past Time--------------------------------------------"
rho_egpt = as.numeric(extract(fit_egpt, "rho")[[1]])
mean = mean(rho_egpt)
crI = quantile(rho_egpt, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_egpt), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.6334
HPD: [0.6052, 0.6617]
crI: [0.6044, 0.6612]
print('---------------------------- Total Duration--------------------------------------------')
[1] "---------------------------- Total Duration--------------------------------------------"
rho_etd = as.numeric(extract(fit_etd, "rho")[[1]])
mean = mean(rho_etd)
crI = quantile(rho_etd, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_etd), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
Mean: 0.8095
HPD: [0.7939, 0.825]
crI: [0.7937, 0.8248]
print('---------------------------- First Pass Regression --------------------------------------------')
[1] "---------------------------- First Pass Regression --------------------------------------------"
rho_ereg = as.numeric(extract(fit_ereg, "rho")[[1]])
mean = mean(rho_ereg)
crI = quantile(rho_ereg, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
Mean: 0.6735
HPD: [0.6487, 0.6993]
crI: [0.6477, 0.6986]
print('---------------------------- Gaze Duration--------------------------------------------')
egd_rand <- extract(fit_egd, "x_rand")[[1]]
# x_rand_filtered <- x_rand[apply(x_rand, 1, function(x) all(x > 0)),]
# x_rand_filtered

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 400), ylim=c(0, 700), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(egd_rand[,1], egd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(egd_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(egd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(egd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Go Past Time--------------------------------------------')
egpt_rand <- extract(fit_egpt, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Go Past Time") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(egpt_rand[,1], egpt_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(egpt_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(egpt_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(egpt_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- Total Duration--------------------------------------------')
etd_rand <- extract(fit_etd, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 1200), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "Total Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(etd_rand[,1], etd_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(etd_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(etd_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(etd_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression --------------------------------------------')
ereg_rand <- extract(fit_ereg, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value 1", ylab = "Eye tracking value 2", main = "First Pass Regression") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(ereg_rand[,1], ereg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(ereg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(ereg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

Bayesian – correlation between MoTR and word level statistics

print("Log Frequency")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$freq)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$freq)$estimate)

# View(stats_cor_df)
stats_cor_df %>% 
  gather(measure, value, c(7, 13)) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

mfreq_temp <- stats_cor_df[c("motr_value", "freq")] %>%
  data.matrix()
efreq_temp <- stats_cor_df[c("eyetr_value", "freq")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(mfreq_temp, pch = 16, col = "blue",
     main = "MoTR RTs and Word Frequency")

# Plot the first data matrix gd_temp
plot(efreq_temp, pch = 16, col = "blue",
     main = "EyeTR RTs and Word Frequency")

motr & frequency

mfreq_data = list(x=mfreq_temp, N=nrow(mfreq_temp))

fit_mfreq = stan(
  file="stan_models/stats_correlation.stan", 
  data=mfreq_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_mfreq@stanmodel@dso <- new("cxxdso")
saveRDS(fit_mfreq, file = paste0("./bayesian_models/bayesian_models_correlation/motr_freq_cor.rds"))

eyetr & frequency

efreq_data = list(x=efreq_temp, N=nrow(efreq_temp))

fit_efreq = stan(
  file="stan_models/stats_correlation.stan", 
  data=efreq_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_efreq@stanmodel@dso <- new("cxxdso")
saveRDS(fit_efreq, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_freq_cor.rds"))
print("Length")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$len)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$len)$estimate)

# View(stats_cor_df)
stats_cor_df %>% 
  gather(measure, value, c(9, 13)) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

mlen_temp <- stats_cor_df[c("motr_value", "len")] %>%
  data.matrix()
elen_temp <- stats_cor_df[c("eyetr_value", "len")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(mlen_temp, pch = 16, col = "blue",
     main = "MoTR RTs and Word Length")

# Plot the first data matrix gd_temp
plot(elen_temp, pch = 16, col = "blue",
     main = "EyeTR RTs and Word Length")

motr & length

mlen_data = list(x=mlen_temp, N=nrow(mlen_temp))

fit_mlen = stan(
  file="stan_models/stats_correlation_len_normal.stan", 
  data=mlen_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_mlen@stanmodel@dso <- new("cxxdso")
saveRDS(fit_mlen, file = paste0("./bayesian_models/bayesian_models_correlation/motr_len_cor.rds"))

eyetr & length

elen_data = list(x=elen_temp, N=nrow(elen_temp))

fit_elen = stan(
  file="stan_models/stats_correlation_len_normal.stan", 
  data=elen_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_elen@stanmodel@dso <- new("cxxdso")
saveRDS(fit_elen, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_len_cor.rds"))
print("Surprisal")
stats_cor_df = provo_df %>% filter(metric == "gaze_duration") %>% spread(measure, value)
print(cor.test(stats_cor_df$motr_value, stats_cor_df$surp)$estimate)
print(cor.test(stats_cor_df$eyetr_value, stats_cor_df$surp)$estimate)

# View(stats_cor_df)
stats_cor_df %>% 
  gather(measure, value, c(8, 13)) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

msurp_temp <- stats_cor_df[c("motr_value", "surp")] %>%
  data.matrix()
esurp_temp <- stats_cor_df[c("eyetr_value", "surp")] %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 2))
# Plot the first data matrix gd_temp
plot(msurp_temp, pch = 16, col = "blue",
     main = "MoTR RTs and Surprisal")

# Plot the first data matrix gd_temp
plot(esurp_temp, pch = 16, col = "blue",
     main = "EyeTR RTs and Surprisal")

motr & surprisal

msurp_data = list(x=msurp_temp, N=nrow(msurp_temp))

fit_msurp = stan(
  file="stan_models/stats_correlation.stan", 
  data=msurp_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_msurp@stanmodel@dso <- new("cxxdso")
saveRDS(fit_msurp, file = paste0("./bayesian_models/bayesian_models_correlation/motr_surp_cor.rds"))

eyetr & surprisal

esurp_data = list(x=esurp_temp, N=nrow(esurp_temp))

fit_esurp = stan(
  file="stan_models/stats_correlation.stan", 
  data=esurp_data, 
  iter=4000, 
  chains=4, 
  cores=8,
  seed=444,
  # control=list(adapt_delta=0.99), 
  # verbose = FALSE
  )

# Save the model 
fit_esurp@stanmodel@dso <- new("cxxdso")
saveRDS(fit_esurp, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_surp_cor.rds"))
fit_mfreq = readRDS("./bayesian_models/bayesian_models_correlation/motr_freq_cor.rds")
fit_efreq = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_freq_cor.rds")
fit_mlen = readRDS("./bayesian_models/bayesian_models_correlation/motr_len_cor.rds")
fit_elen = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_len_cor.rds")
fit_msurp = readRDS("./bayesian_models/bayesian_models_correlation/motr_surp_cor.rds")
fit_esurp = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_surp_cor.rds")

print('---------------------------- MoTR & Log Frequency --------------------------------------------')
print(fit_mfreq)
print('---------------------------- EyeTR & Log Frequency --------------------------------------------')
print(fit_efreq)
print('---------------------------- MoTR & Length --------------------------------------------')
print(fit_mlen)
print('---------------------------- EyeTR & Length --------------------------------------------')
print(fit_elen)
print('---------------------------- MoTR & Surprisal --------------------------------------------')
print(fit_msurp)
print('---------------------------- EyeTR & Surprisal --------------------------------------------')
print(fit_esurp)
# MoTR & Log Freq
stan_trace(fit_mfreq)
stan_dens(fit_mfreq, separate_chains = TRUE)
stan_plot(fit_mfreq)

# EyeTR & Log Freq
stan_trace(fit_efreq)
stan_dens(fit_efreq, separate_chains = TRUE)
stan_plot(fit_efreq)

# MoTR & Len
stan_trace(fit_mlen)
stan_dens(fit_mlen, separate_chains = TRUE)
stan_plot(fit_mlen)

# EyeTR & Len
stan_trace(fit_elen)
stan_dens(fit_elen, separate_chains = TRUE)
stan_plot(fit_elen)

# MoTR & Surprisal
stan_trace(fit_msurp)
stan_dens(fit_msurp, separate_chains = TRUE)
stan_plot(fit_msurp)

# EyeTR & Surprisal
stan_trace(fit_esurp)
stan_dens(fit_esurp, separate_chains = TRUE)
stan_plot(fit_esurp)
print('---------------------------- MoTR & Log Freq --------------------------------------------')
rho_mfreq = as.numeric(extract(fit_mfreq, "rho")[[1]])
mean = mean(rho_mfreq)
crI = quantile(rho_mfreq, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mfreq), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- EyeTR & Log Freq --------------------------------------------')
rho_efreq = as.numeric(extract(fit_efreq, "rho")[[1]])
mean = mean(rho_efreq)
crI = quantile(rho_efreq, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_efreq), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- MoTR & Length --------------------------------------------')
rho_mlen = as.numeric(extract(fit_mlen, "rho")[[1]])
mean = mean(rho_mlen)
crI = quantile(rho_mlen, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_mlen), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- EyeTR & Length --------------------------------------------')
rho_elen = as.numeric(extract(fit_elen, "rho")[[1]])
mean = mean(rho_elen)
crI = quantile(rho_elen, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_elen), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- MoTR & Surprisal --------------------------------------------')
rho_msurp = as.numeric(extract(fit_msurp, "rho")[[1]])
mean = mean(rho_msurp)
crI = quantile(rho_msurp, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_msurp), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")

print('---------------------------- EyeTR & Surprisal --------------------------------------------')
rho_esurp = as.numeric(extract(fit_esurp, "rho")[[1]])
mean = mean(rho_esurp)
crI = quantile(rho_esurp, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_esurp), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]")
print('---------------------------- MoTR & Log Frequency--------------------------------------------')
mfreq_rand <- extract(fit_mfreq, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 12), type="n",
     xlab = "MoTR value", ylab = "Log Frequency", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mfreq_rand[,1], mfreq_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(mfreq_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mfreq_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mfreq_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- EyeTR & Log Frequency--------------------------------------------')
efreq_rand <- extract(fit_efreq, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 500), ylim=c(0, 12), type="n",
     xlab = "Eye tracking value", ylab = "Log Frequency", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(efreq_rand[,1], efreq_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(efreq_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(efreq_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(efreq_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- MoTR & Length --------------------------------------------')
mlen_rand <- extract(fit_mlen, "x_rand")[[1]]
# mlen_rand

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "MoTR value", ylab = "Word Length", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(mlen_rand[,1], mlen_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(mlen_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(mlen_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(mlen_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- EyeTR & Length --------------------------------------------')
elen_rand <- extract(fit_elen, "x_rand")[[1]]
# elen_rand

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "EyeTR value", ylab = "Word Length", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(elen_rand[,1], elen_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(elen_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(elen_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(elen_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- MoTR & Surprisal --------------------------------------------')
msurp_rand <- extract(fit_msurp, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "MoTR value", ylab = "Word Surprisal", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(msurp_rand [,1], msurp_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(msurp_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(msurp_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(msurp_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- EyeTR & Surprisal --------------------------------------------')
esurp_rand <- extract(fit_esurp, "x_rand")[[1]]

# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 800), ylim=c(0, 20), type="n",
     xlab = "EyeTR value", ylab = "Word Surprisal", main = "Gaze Duration") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(esurp_rand [,1], esurp_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(esurp_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(esurp_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(esurp_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
print("EyeTR vs. EyeTR Fisrt Pass Regression Prob. < 0.3 ")

ereg_df = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
         eyetr_value_2 = pmax(value_2, 1e-5))

ereg_df_low = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
         eyetr_value_2 = pmax(value_2, 1e-5)) %>%
  filter(eyetr_value_1 < 0.3)
# View(ereg_df_low)

ereg_df_high = provo_eyetr_grouped_df %>% filter(metric == "FPReg") %>% distinct() %>% #group_by(text_id, metric, measure) %>%
  # summarize(value = mean(value)) %>%
  filter(!(row_number() %in% c(443, 444, 445, 446))) %>%
    spread(measure, value) %>%
  # smoothing, if includes 0s
  mutate(eyetr_value_1 =  pmax(value_1, 1e-5),
         eyetr_value_2 = pmax(value_2, 1e-5)) %>%
  filter(eyetr_value_1 >= 0.3)
# View(ereg_df_high) 

print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$estimate)
print(cor.test(ereg_df$eyetr_value_1, ereg_df$eyetr_value_2)$p.value)
print(cor.test(ereg_df_low$eyetr_value_1, ereg_df_low$eyetr_value_2)$estimate)
print(cor.test(ereg_df_low$eyetr_value_1, ereg_df_low$eyetr_value_2)$p.value)
print(cor.test(ereg_df_high$eyetr_value_1, ereg_df_high$eyetr_value_2)$estimate)
print(cor.test(ereg_df_high$eyetr_value_1, ereg_df_high$eyetr_value_2)$p.value)

# View(egd_df)

ereg_df %>% 
  gather(measure, value, 5:6) %>%
  ggplot(aes(x = value)) +
  geom_density() +
  facet_wrap(~measure, scales = "free") +
  theme_bw() +
  scale_fill_brewer(palette = "Set1")

ereg_temp <- ereg_df[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()
ereg_temp_low <- ereg_df_low[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()
ereg_temp_high <- ereg_df_high[c("eyetr_value_1", "eyetr_value_2")] %>%
  drop_na() %>%
  data.matrix()

# Set up the plotting area with two side-by-side plots
par(mfrow = c(1, 3))
# Plot the first data matrix gd_temp
plot(ereg_temp, pch = 16, col = "blue",
     main = "FPReg all data Not Log-Transformed")
plot(ereg_temp_low, pch = 16, col = "blue",
     main = "FPReg < 0.3 Not Log-Transformed")
plot(ereg_temp_high, pch = 16, col = "blue",
     main = "FPReg > 0.3 Not Log-Transformed")
# -------fit model eyetr vs. eyetr FPReg <0.3 & >=0.3 ----------
reg_data = list(x=ereg_temp, N=nrow(ereg_temp))
fit_reg = stan(
  # file="stan_models/bivariate_beta_correlation_reg.stan", 
  file = "stan_models/bivariate_normal_reg.stan",
  data=reg_data, 
  iter=4000, 
  chains=4, 
  cores=4,
  seed=444,
  # control=list(adapt_delta=0.99), 
  verbose = FALSE
  )

# Save the model 
fit_reg@stanmodel@dso <- new("cxxdso")
saveRDS(fit_reg, file = paste0("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_all_data.rds"))

exploratory: divide eye tracking regression data into two parts.

# fit_ereg_all = readRDS("./eyetr_eyetr_FPReg_cor_all_data.rds")
fit_ereg_all = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor.rds")
fit_ereg_low = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_00-03.rds")
fit_ereg_high = readRDS("./bayesian_models/bayesian_models_correlation/eyetr_eyetr_FPReg_cor_03-1.rds")

print('---------------------------- First Pass Regression Prob. all data --------------------------------------------')
print(fit_ereg_all)
print('---------------------------- First Pass Regression Prob.< 0.3--------------------------------------------')
print(fit_ereg_low)
print('---------------------------- First Pass Regression Prob.>= 0.3--------------------------------------------')
print(fit_ereg_high)
# # FPReg all data
stan_trace(fit_ereg_all)
stan_dens(fit_ereg_all, separate_chains = TRUE)
stan_plot(fit_ereg_all)

# # FPReg < 0.3
stan_trace(fit_ereg_low)
stan_dens(fit_ereg_low, separate_chains = TRUE)
stan_plot(fit_ereg_low)

# FPReg >= 0.3
stan_trace(fit_ereg_high)
stan_dens(fit_ereg_high, separate_chains = TRUE)
stan_plot(fit_ereg_high)
print('---------------------------- First Pass Regression all data--------------------------------------------')
rho_ereg_all = as.numeric(extract(fit_ereg_all, "rho")[[1]])
mean = mean(rho_ereg_all)
crI = quantile(rho_ereg_all, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_all), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")


print('---------------------------- First Pass Regression < 0.3--------------------------------------------')
rho_ereg_low = as.numeric(extract(fit_ereg_low, "rho")[[1]])
mean = mean(rho_ereg_low)
crI = quantile(rho_ereg_low, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_low), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")


print('---------------------------- First Pass Regression >= 0.3--------------------------------------------')
rho_ereg_high = as.numeric(extract(fit_ereg_high, "rho")[[1]])
mean = mean(rho_ereg_high)
crI = quantile(rho_ereg_high, c(.025, .975))
hpd99 = HPDinterval(as.mcmc(rho_ereg_high), prob=0.95)
cat("Mean: ", mean, "\nHPD: [", hpd99[,"lower"], ", ", hpd99[,"upper"], "]", sep="", "\ncrI: [", crI[1], ", ", crI[2], "]\n")
print('---------------------------- First Pass Regression all data --------------------------------------------')
eallreg_rand <- extract(fit_ereg_all, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(eallreg_rand[,1], eallreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(eallreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(eallreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression < 0.3 --------------------------------------------')
elowreg_rand <- extract(fit_ereg_low, "x_rand")[[1]]
# print(elowreg_rand)
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(elowreg_rand[,1], elowreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp_low, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(elowreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(elowreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")

print('---------------------------- First Pass Regression >= 0.3 --------------------------------------------')
ehighreg_rand_samples <- extract(fit_ereg_high, "x_rand")[[1]]
# print(mhighreg_rand_samples)
selected_indices <- sample(1:nrow(ehighreg_rand_samples), 900)
ehighreg_rand <- ehighreg_rand_samples[selected_indices, ]
# mhighreg_rand <- extract(fit_mreg_high, "x_rand")[[1]]
# create a blank plot first with appropriate limits
plot(1, 1, xlim=c(0, 1), ylim=c(0, 1), type="n",
     xlab = "Eye tracking value", ylab = "MoTR value", main = "FPReg") # 'type = "n"' makes sure the plot is blank

# add points for x_rand with color 
points(ehighreg_rand[,1], ehighreg_rand[,2], col = "black", pch = 16)
# add points for gd_temp with color red
points(ereg_temp_high, pch=16, col="red")

# add dataEllipse with color 
dataEllipse(ehighreg_rand, levels = c(0.5, 0.75), fill=T, plot.points = F, col="orange")
dataEllipse(ehighreg_rand, levels = c(0.95, 0.99), fill=T, plot.points = F, col="blue")
LS0tCnRpdGxlOiAiQ29ycmVsYXRpb24gQW5hbHlzaXMgZm9yIE1vVFIgb24gUHJvdm8gRGF0YSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnNoaGggPC0gc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzICMgSXQncyBhIGxpYnJhcnksIHNvIHNoaGghCgpzaGhoKGxpYnJhcnkoIG1nY3YgKSkKc2hoaChsaWJyYXJ5KGRwbHlyKSkKc2hoaChsaWJyYXJ5KGdncGxvdDIpKQpzaGhoKGxpYnJhcnkobG1lNCkpCnNoaGgobGlicmFyeSh0aWR5bXYpKQpzaGhoKGxpYnJhcnkoZ2FtbHNzKSkKc2hoaChsaWJyYXJ5KGdzdWJmbikpCnNoaGgobGlicmFyeShsbWVyVGVzdCkpCnNoaGgobGlicmFyeSh0aWR5dmVyc2UpKQpzaGhoKGxpYnJhcnkoYm9vdCkpCnNoaGgobGlicmFyeShyc2FtcGxlKSkKc2hoaChsaWJyYXJ5KHBsb3RyaXgpKQpzaGhoKGxpYnJhcnkoZ2dyZXBlbCkpCnNoaGgobGlicmFyeShtZ2N2KSkKCnNoaGgobGlicmFyeShicm1zKSkKc2hoaChsaWJyYXJ5KGJheWVzcGxvdCkpCnNoaGgobGlicmFyeShwYXRjaHdvcmspKQpzaGhoKGxpYnJhcnkoTUFTUykpCnNoaGgobGlicmFyeSh0aWR5cikpCnNoaGgobGlicmFyeShleHRyYURpc3RyKSkKc2hoaChsaWJyYXJ5KHB1cnJyKSkKIyBGb3IgZXhlcmNpc2VzIHdpdGggU3RhbiBjb2RlCnNoaGgobGlicmFyeShyc3RhbikpCm9wdGlvbnMobWMuY29yZXMgPSBwYXJhbGxlbDo6ZGV0ZWN0Q29yZXMoKSkKcnN0YW5fb3B0aW9ucyhhdXRvX3dyaXRlID0gRkFMU0UpCgpzaGhoKGxpYnJhcnkoY2FyKSkKc2hoaChsaWJyYXJ5KGNvZGEpKQpzaGhoKGxpYnJhcnkoZ3JpZEV4dHJhKSkKCnRoZW1lX3NldCh0aGVtZV9idygpKQpvcHRpb25zKGRpZ2l0cz00KQpvcHRpb25zKHNjaXBlbj05OTkpCnNldC5zZWVkKDQ0NCkKcGlwZV9tZXNzYWdlID0gZnVuY3Rpb24oLmRhdGEsIHN0YXR1cykge21lc3NhZ2Uoc3RhdHVzKTsgLmRhdGF9CgpgYGAKCgojIFJlYWQgaW4gTW9UUiBEYXRhCgpgYGB7cn0KCnJhdGUgPSAxNjAKCmZpbGVfcHJlZml4ID0gIi4uL2RhdGEvcHJvdm9fZjE2MC8iCmZuYW1lcyA9IGxpc3QuZmlsZXMocGF0aD1maWxlX3ByZWZpeCkKCmRmID0gZGF0YS5mcmFtZSgpCmZvciAoZiBpbiBmbmFtZXMpIHsKICB0ZW1wID0gcmVhZC5jc3YocGFzdGUwKGZpbGVfcHJlZml4LCAiLyIsIGYpKSAlPiUKICAgIG11dGF0ZShzdWJqID0gc3RyX3JlbW92ZShmLCAiX3JlYWRpbmdfbWVhc3VyZXMuY3N2IikpCiAgZGYgPSByYmluZChkZiwgdGVtcCkKfQoKIyBGaWx0ZXIgb3V0IHJlYWRlcnMgd2hvc2UgYWNjdXJhY3kgdG8gdGhlIGNvbXByZWhlbnNpb24gcXVlc3Rpb25zIHdlcmUgbGVzcyB0aGFuIDgwJS4KZmlsdGVyX2RmID0gZGYgJT4lCiAgZ3JvdXBfYnkocGFyYV9uciwgc3ViaikgJT4lIHN1bW1hcmlzZShjb3JyZWN0ID0gaWZfZWxzZSh1bmlxdWUoY29ycmVjdG5lc3MpID09IDEsIDEsIDApKSAlPiUgdW5ncm91cCgpICU+JQogIGRyb3BfbmEoKSAlPiUKICBncm91cF9ieShzdWJqKSAlPiUgc3VtbWFyaXNlKHBfY29ycmVjdCA9IG1lYW4oY29ycmVjdCkpICU+JSB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKHBfY29ycmVjdCA9IHJvdW5kKHBfY29ycmVjdCwgZGlnaXRzID0gMikpCgpmaWx0ZXJfZGYgPSBmaWx0ZXJfZGYgJT4lIGZpbHRlcihwX2NvcnJlY3QgPCAwLjgpCmZpbHRlcl9saXN0ID0gZmlsdGVyX2RmJHN1YmoKcGlsb3RfZXhjZXB0aW9ucyA8LSBjKCJyZWFkZXJfMjU1IiwgInJlYWRlcl8yNTYiLCAicmVhZGVyXzI1OSIsICJyZWFkZXJfMjYxIiwgInJlYWRlcl8yNjIiLCAicmVhZGVyXzI2MyIpCgpyYXdfZGYgPSBkZiAlPiUKICBmaWx0ZXIoISBzdWJqICVpbiUgYyhmaWx0ZXJfbGlzdCkgfCAoc3ViaiAlaW4lIHBpbG90X2V4Y2VwdGlvbnMpKSAlPiUKICBtdXRhdGUod29yZCA9IHN0cl90cmltKHdvcmQpKSAlPiUKICBtdXRhdGUoc3ViaiA9IHN0cl9yZW1vdmUoc3ViaiwgInJlYWRlcl8iKSkgJT4lCiAgbXV0YXRlKHN1YmogPSBhcy5jaGFyYWN0ZXIoc3ViaikpICU+JQogIG11dGF0ZShGUFJlZyA9IGlmX2Vsc2UodG90YWxfZHVyYXRpb24gPT0gMCwgLTEsIEZQUmVnKSkgJT4lICNJZiB0aGUgd29yZCBpcyBza2lwcGVkIHdlIGNhbid0IHNheSB0aGF0IGl0IHdhc24ndCByZWdyZXNzZWQgb24gdGhlIGZpcnN0IHBhc3MuIFNldCB0byBhICJOQSIKICBkcGx5cjo6c2VsZWN0KGV4cHJfaWQsIGNvbmRfaWQsIHBhcmFfbnIsIHdvcmQsIHdvcmRfbnIsIGZpcnN0X2R1cmF0aW9uLCB0b3RhbF9kdXJhdGlvbiwgZ2F6ZV9kdXJhdGlvbiwgZ29fcGFzdF90aW1lLCBGUFJlZywgc3ViaikKbGVuZ3RoKHVuaXF1ZShyYXdfZGYkc3ViaikpCgpkZiAlPiUKICBmaWx0ZXIoISBzdWJqICVpbiUgYyhmaWx0ZXJfbGlzdCkgfCAoc3ViaiAlaW4lIHBpbG90X2V4Y2VwdGlvbnMpKSAlPiUKICBmaWx0ZXIoRlBSZWcgPj0gMCkgJT4lCiAgZHBseXI6OnNlbGVjdChGUFJlZykgJT4lCiAgZHJvcF9uYSgpICU+JQogIHN1bW1hcmlzZSggbSA9IG1lYW4oRlBSZWcpKQoKZGYgJT4lCiAgZmlsdGVyKCEgc3ViaiAlaW4lIGMoZmlsdGVyX2xpc3QpIHwgKHN1YmogJWluJSBwaWxvdF9leGNlcHRpb25zKSkgJT4lCiAgZHBseXI6OnNlbGVjdChGUEZpeCkgJT4lCiAgZHJvcF9uYSgpICU+JQogIHN1bW1hcmlzZSggbSA9IG1lYW4oRlBGaXgpKQoKCmBgYAoKYGBge3J9CiMgVmlldyhyYXdfZGYpCmBgYAoKCmBgYHtyfQojIEF2ZXJhZ2UgYWNyb3NzIHN1YmplY3RzCm1vdHJfYWdnX2RmID0gcmF3X2RmICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCA2OjEwKSAlPiUKICAgIGZpbHRlcih2YWx1ZSA+PSAwKSAlPiUgI1JlbW92ZXMgdGhlICJOQSIgdmFsdWVzIGZvciBGUFJlZwogIAogICAgIyA9PT09IFJlbW92ZSBza2lwcGVkIHdvcmRzCiAgICAjIG11dGF0ZSh6ZXJvID0gaWZfZWxzZShtZXRyaWMgIT0gIkZQUmVnIiAmIHZhbHVlID09IDAsVCwgRikpICU+JQogICAgIyBmaWx0ZXIoemVybyA9PSBGKSAlPiUKICAKICAgIGRyb3BfbmEoKSAlPiUKICAgIGdyb3VwX2J5KHBhcmFfbnIsIHdvcmRfbnIsIHdvcmQsIG1ldHJpYykgJT4lCiAgICAKICAgICMgPT09IFJlbW92ZSBvdXRsaWVycyA+IDNTRAogICAgICAjIG11dGF0ZShvdXRsaWVyID0gaWZfZWxzZShtZXRyaWMgIT0gIkZQUmVnIiAmIHZhbHVlID4gKG1lYW4odmFsdWUpICsgMyAqIHNkKHZhbHVlKSksIFQsIEYpKSAlPiUgZmlsdGVyKG91dGxpZXIgPT0gRikgJT4lCiAgCiAgICAgIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpLCBuc3ViaiA9IGxlbmd0aCh1bmlxdWUoc3ViaikpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShwYXJhX25yLCB3b3JkX25yKSAlPiUKICByZW5hbWUodGV4dF9pZCA9IHBhcmFfbnIsIHdvcmRfdGV4dF9pZHggPSB3b3JkX25yLCBtb3RyX3ZhbHVlID0gdmFsdWUpCiMgVmlldyhtb3RyX2FnZ19kZikKCmBgYAoKCgoKIyBDb21wYXJpc29uIHRvIFByb3ZvCgoKYGBge3J9CiMgUmVhZCBpbiBQcm92byBzdXJwcmlzYWwsIGZyZXF1ZW5jeSBhbmQgbGVuZ3RoIGRhdGEKcHJvdm9fbW9kZWxpbmdfZGYgPSByZWFkLmNzdigiLi4vZGF0YS9wcm92b19zdGF0cy5jc3YiKSAlPiUKICBkcGx5cjo6c2VsZWN0KHRleHRfaWQsIHNlbnRfaWQsIHRyaWdnZXJfaWR4LCB3b3JkLCBmcmVxLCBzdXJwLCBsZW4pICU+JQogIHJlbmFtZSh3b3JkX2lkeCA9IHRyaWdnZXJfaWR4KQoKcHJvdm9fbW9kZWxpbmdfZGYKCmBgYAoKYGBge3J9CiMgUmVhZCBpbiBQcm92byBleWV0cmFja2luZyBkYXRhCgpwcm92b19yYXdfZGYgPSByZWFkLmNzdigiLi4vZGF0YS9wcm92b19leWV0cmFja2luZy5jc3YiKQoKYGBgCgpgYGB7cn0KCiMgdW5pcXVlKHByb3ZvX3Jhd19kZiRQYXJ0aWNpcGFudF9JRCkKIyBsZW5ndGgodW5pcXVlKHByb3ZvX3Jhd19kZiRQYXJ0aWNpcGFudF9JRCkpCgpwcm92b19leWV0cmFja2luZ19kZiA9IHByb3ZvX3Jhd19kZiAlPiUKICBkcGx5cjo6c2VsZWN0KFBhcnRpY2lwYW50X0lELCBUZXh0X0lELCBTZW50ZW5jZV9OdW1iZXIsIFdvcmRfSW5fU2VudGVuY2VfTnVtYmVyLCBXb3JkLCBXb3JkX051bWJlciwgSUFfRklSU1RfRklYX1BST0dSRVNTSVZFLCBJQV9GSVJTVF9SVU5fRFdFTExfVElNRSwgSUFfRFdFTExfVElNRSwgSUFfUkVHUkVTU0lPTl9QQVRIX0RVUkFUSU9OLCBJQV9SRUdSRVNTSU9OX09VVCwgSUFfU0tJUCkgJT4lCiAgcmVuYW1lKCAjZmlyc3RfZHVyYXRpb24gPSBJQV9GSVJTVF9GSVhBVElPTl9EVVJBVElPTiwgICAKICAgICAgICAgIGdhemVfZHVyYXRpb24gPSBJQV9GSVJTVF9SVU5fRFdFTExfVElNRSwKICAgICAgICAgIHRvdGFsX2R1cmF0aW9uID0gSUFfRFdFTExfVElNRSwKICAgICAgICAgIGdvX3Bhc3RfdGltZSA9IElBX1JFR1JFU1NJT05fUEFUSF9EVVJBVElPTiwKICAgICAgICAgIHN1YmogPSBQYXJ0aWNpcGFudF9JRCwKICAgICAgICAgIHRleHRfaWQgPSBUZXh0X0lELAogICAgICAgICAgc2VudF9pZCA9IFNlbnRlbmNlX051bWJlciwKICAgICAgICAgIHdvcmRfaWR4ID0gV29yZF9Jbl9TZW50ZW5jZV9OdW1iZXIsCiAgICAgICAgICB3b3JkX3RleHRfaWR4ID0gV29yZF9OdW1iZXIsICAgIyBJQV9JRD8KICAgICAgICAgIHdvcmQgPSBXb3JkLCAgICAgICMgV29yZD8KICAgICAgICAgIEZQUmVnID0gSUFfUkVHUkVTU0lPTl9PVVQsCiAgICAgICAgICBza2lwID0gSUFfU0tJUCwKICAgICAgICAgIGZmX3Byb2dyZXNzaXZlID0gSUFfRklSU1RfRklYX1BST0dSRVNTSVZFKSAlPiUKICBtdXRhdGUoZmlyc3RfZHVyYXRpb24gPSBnYXplX2R1cmF0aW9uKSAlPiUKICBtdXRhdGUoZ2F6ZV9kdXJhdGlvbiA9IGlmX2Vsc2UoZmZfcHJvZ3Jlc3NpdmUgPT0gMCwgMCwgYXMuZG91YmxlKGdhemVfZHVyYXRpb24pKSwKICAgICAgICAgZ29fcGFzdF90aW1lID0gaWZfZWxzZShmZl9wcm9ncmVzc2l2ZSA9PSAwLCAwLCBhcy5kb3VibGUoZ29fcGFzdF90aW1lKSkpICU+JQogIGRwbHlyOjpzZWxlY3QoLWZmX3Byb2dyZXNzaXZlKSAlPiUKICAKICBtdXRhdGUoCiAgICBnYXplX2R1cmF0aW9uID0gaWZfZWxzZSh0b3RhbF9kdXJhdGlvbiA9PSAwLCAwLCBhcy5kb3VibGUoZ2F6ZV9kdXJhdGlvbikpLAogICAgICBnb19wYXN0X3RpbWUgPSBpZl9lbHNlKHRvdGFsX2R1cmF0aW9uID09IDAsIDAsIGFzLmRvdWJsZShnb19wYXN0X3RpbWUpKSwKICAgICAgRlBSZWcgPSBpZl9lbHNlKHRvdGFsX2R1cmF0aW9uID09IDAsIC0xLCBhcy5kb3VibGUoRlBSZWcpKSwKICAgICAgZmlyc3RfZHVyYXRpb24gPSAgaWZfZWxzZSh0b3RhbF9kdXJhdGlvbiA9PSAwLCAwLCBhcy5kb3VibGUoZmlyc3RfZHVyYXRpb24pKSwKICApICU+JQogIGdhdGhlcihtZXRyaWMsIHZhbHVlLCA3OjEyKSAlPiUKICBmaWx0ZXIodmFsdWUgPj0gMCkgJT4lICAgICAgICAgICMgZmlsdGVyIHNraXBwZWQgd29yZCBpbiBleWUgdHJhY2tpbmcgZGF0YSBmb3IgRlBSZWcKICAKICAjID09PT0gUmVtb3ZlIHNraXBwZWQgd29yZHMKICAjIG11dGF0ZSh6ZXJvID0gaWZfZWxzZShtZXRyaWMgIT0gIkZQUmVnIiAmIHZhbHVlID09IDAsVCwgRikpICU+JQogICMgZmlsdGVyKHplcm8gPT0gRikgJT4lCiAgCiAgIyBtdXRhdGUodmFsdWUgPSBpZl9lbHNlKGlzLm5hKHZhbHVlKSwgYXMuaW50ZWdlcigwKSwgYXMuaW50ZWdlcih2YWx1ZSkpKSAlPiUKICAjIG11dGF0ZSh2YWx1ZSA9IGlmX2Vsc2UobWV0cmljICE9ICJGUFJlZyIgJiBpcy5uYSh2YWx1ZSksIGFzLmludGVnZXIoMCksIGFzLmludGVnZXIodmFsdWUpKSkgJT4lCiAgZHJvcF9uYSgpICU+JQogIG11dGF0ZSh3b3JkID0gc3RyX3RyaW0od29yZCkpICU+JQogIG11dGF0ZShzdWJqID0gc3RyX3JlbW92ZShzdWJqLCAiU3ViIikpICU+JQogIG11dGF0ZShzdWJqID0gYXMuaW50ZWdlcihzdWJqKSkgJT4lCiAgICBncm91cF9ieSh0ZXh0X2lkLCB3b3JkX3RleHRfaWR4LCBzZW50X2lkLCB3b3JkX2lkeCwgd29yZCwgbWV0cmljKSAlPiUKICAKICAjID09PSBSZW1vdmUgb3V0bGllcnMgPiAzU0QKICAgICMgbXV0YXRlKG91dGxpZXIgPSBpZl9lbHNlKCEgbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgdmFsdWUgPiAobWVhbih2YWx1ZSkgKyAzICogc2QodmFsdWUpICksIFQsIEYpKSAlPiUKICAgICMgZmlsdGVyKG91dGxpZXIgPT0gRikgJT4lCiAgCiAgdW5ncm91cCgpICMlPiUKCiMgQWdncmVnYXRlIGNyb3NzLXBhcnRpY2lwYW50IGRhdGEgZm9yIGFsbCBzdWJqZWN0cwpwcm92b19leWV0cmFja2luZ19hZ2dfZGYgPSBwcm92b19leWV0cmFja2luZ19kZiAlPiUKICBncm91cF9ieSh0ZXh0X2lkLCB3b3JkX3RleHRfaWR4LCBzZW50X2lkLCB3b3JkX2lkeCwgd29yZCwgbWV0cmljKSAlPiUKICAgIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpLAogICAgICAgICAgICAgIG5zdWJqID0gbGVuZ3RoKHVuaXF1ZShzdWJqKSkpICU+JQogICAgdW5ncm91cCgpCgpwcm92b19yYXdfZGYgJT4lCiAgZHBseXI6OnNlbGVjdChJQV9SRUdSRVNTSU9OX09VVCkgJT4lCiAgZHJvcF9uYSgpICU+JQogIHN1bW1hcmlzZSggbSA9IG1lYW4oSUFfUkVHUkVTU0lPTl9PVVQpKQoKcHJvdm9fcmF3X2RmICU+JQogIGRwbHlyOjpzZWxlY3QoSUFfU0tJUCkgJT4lCiAgZHJvcF9uYSgpICU+JQogIHN1bW1hcmlzZSggbSA9IG1lYW4oSUFfU0tJUCkpCgpgYGAKCmBgYHtyfQoKIyBTcGxpdCB0aGUgZXlldHJhY2tpbmcgZGF0YSBpbiB0d28gYnkgc3ViamVjdHMgdG8gc2VlIGhvdyB3ZWxsIGl0IGNvcnJlbGF0ZXMgd2l0aCBpdHNlbGYKcHJvdm9fZXlldHJhY2tpbmdfc3ViajFfZGZfdGVtcCA9IHByb3ZvX2V5ZXRyYWNraW5nX2RmICU+JQogIGZpbHRlcihzdWJqIDw9IDQyKSAlPiUKICBtdXRhdGUod29yZF90ZXh0X2lkeCA9IGFzLmludGVnZXIod29yZF90ZXh0X2lkeCAtIDEpKSAlPiUKICBncm91cF9ieSh0ZXh0X2lkLCB3b3JkX3RleHRfaWR4LCBzZW50X2lkLCB3b3JkX2lkeCwgd29yZCwgbWV0cmljKSAlPiUKICAgIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgcmVuYW1lKHZhbHVlXzEgPSB2YWx1ZSkgIyU+JQogICMgZHBseXI6OnNlbGVjdCgtc2VudF9pZCwgLXdvcmRfaWR4KQoKCnByb3ZvX2V5ZXRyYWNraW5nX3N1YmoxX2RmID0gbWVyZ2UocHJvdm9fZXlldHJhY2tpbmdfc3ViajFfZGZfdGVtcCwgbW90cl9hZ2dfZGYsIGJ5PWMoInRleHRfaWQiLCAid29yZF90ZXh0X2lkeCIsICJtZXRyaWMiKSkgJT4lCiAgYXJyYW5nZSh0ZXh0X2lkLCBzZW50X2lkLCB3b3JkX2lkeCkgJT4lCiAgZmlsdGVyKCEodGV4dF9pZCA9PSAxMyAmIHdvcmRfdGV4dF9pZHggPj0gMjAgJiB3b3JkX3RleHRfaWR4IDw9IDUyKSkgJT4lCiAgZmlsdGVyKCEodGV4dF9pZCA9PSAzICYgd29yZF90ZXh0X2lkeCA+PSA0NiAmIHdvcmRfdGV4dF9pZHggPD0gNTcpKSAlPiUKICByZW5hbWUod29yZCA9IHdvcmQueSkgJT4lCiAgZHBseXI6OnNlbGVjdCh0ZXh0X2lkLCB3b3JkX3RleHRfaWR4LCBtZXRyaWMsIHdvcmQsIHZhbHVlXzEpIAoKIyBWaWV3KHByb3ZvX2V5ZXRyYWNraW5nX3N1YmoxX2RmKQoKcHJvdm9fZXlldHJhY2tpbmdfc3ViajJfZGYgPSBwcm92b19leWV0cmFja2luZ19kZiAlPiUKICBmaWx0ZXIoc3ViaiA+IDQyKSAlPiUKICBtdXRhdGUod29yZF90ZXh0X2lkeCA9IGFzLmludGVnZXIod29yZF90ZXh0X2lkeCAtIDEpKSAlPiUKICBncm91cF9ieSh0ZXh0X2lkLCB3b3JkX3RleHRfaWR4LCBzZW50X2lkLCB3b3JkX2lkeCwgd29yZCwgbWV0cmljKSAlPiUKICAgIHN1bW1hcmlzZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgICByZW5hbWUodmFsdWVfMiA9IHZhbHVlKSU+JQogIGRwbHlyOjpzZWxlY3QoLXNlbnRfaWQsIC13b3JkX2lkeCkKCiMgVmlldyhwcm92b19leWV0cmFja2luZ19zdWJqMl9kZikKICAKcHJvdm9fZXlldHJfZ3JvdXBlZF9kZiA9IG1lcmdlKHByb3ZvX2V5ZXRyYWNraW5nX3N1YmoyX2RmLCBwcm92b19leWV0cmFja2luZ19zdWJqMV9kZiwgYnk9YygidGV4dF9pZCIsICJ3b3JkX3RleHRfaWR4IiwgIm1ldHJpYyIpKSAlPiUKICAjIGZpbHRlcih3b3JkLnggPT0gd29yZC55KSAlPiUKICBkcGx5cjo6c2VsZWN0KC13b3JkLnkpICU+JQogICMgPT09IFJlbW92ZSBvdXRsaWVycyA+IDNTRAogICMgZ3JvdXBfYnkobWV0cmljKSAlPiUKICAjICAgbXV0YXRlKG1vdHJfb3V0bGllciA9IGlmX2Vsc2UoISBtZXRyaWMgJWluJSBjKCJGUFJlZyIsICJza2lwIikgJiB2YWx1ZV8xID4gKG1lYW4odmFsdWVfMSkgKyAzICogc2QodmFsdWVfMSkgKSwgVCwgRikpICU+JQogICMgICBmaWx0ZXIobW90cl9vdXRsaWVyID09IEYpICU+JQogICMgICBtdXRhdGUoZXlldHJfb3V0bGllciA9IGlmX2Vsc2UoISBtZXRyaWMgJWluJSBjKCJGUFJlZyIsICJza2lwIikgJiB2YWx1ZV8yID4gKG1lYW4odmFsdWVfMikgKyAzICogc2QodmFsdWVfMikgKSwgVCwgRikpICU+JQogICMgICBmaWx0ZXIoZXlldHJfb3V0bGllciA9PSBGKSAlPiUKICAjIHVuZ3JvdXAoKSAlPiUKICAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIGMoInZhbHVlXzEiLCAidmFsdWVfMiIpKSAjJT4lCiAgIyBkcGx5cjo6c2VsZWN0KC1tb3RyX291dGxpZXIsIC1leWV0cl9vdXRsaWVyKQoKIyBWaWV3KHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYpCgpgYGAKCgpgYGB7cn0KcHJvdm9fZGYgPSBtZXJnZShwcm92b19leWV0cmFja2luZ19hZ2dfZGYsIHByb3ZvX21vZGVsaW5nX2RmLCBieT1jKCJ0ZXh0X2lkIiwgInNlbnRfaWQiLCAid29yZF9pZHgiKSkgJT4lCiAgbXV0YXRlKHdvcmRfdGV4dF9pZHggPSBhcy5pbnRlZ2VyKHdvcmRfdGV4dF9pZHggLSAxKSkgJT4lCiAgYXJyYW5nZSh0ZXh0X2lkLCBzZW50X2lkLCB3b3JkX2lkeCkgJT4lCiAgcmVuYW1lKGV5ZXRyX3ZhbHVlID0gdmFsdWUpIAoKcHJvdm9fZGYgPSBtZXJnZShwcm92b19kZiwgbW90cl9hZ2dfZGYsIGJ5PWMoInRleHRfaWQiLCAid29yZF90ZXh0X2lkeCIsICJtZXRyaWMiKSkgJT4lCmFycmFuZ2UodGV4dF9pZCwgc2VudF9pZCwgd29yZF9pZHgpICU+JQogICMgYWxtb3N0IGFsbCB0aGUgd29yZC54ICE9IHdvcmQueSBpcyBiZWNhdXNlIG9mIG5vcm1hbGl6YXRpb24gcHJvYmxlbSwgc28gd2UgY2FuIGtlZXAgdGhlbSwgaW5zdGVhZCwgZGVsZXRpbmcgc29tZSBzcGVjaWFsIGNhc2VzCmZpbHRlcighKHRleHRfaWQgPT0gMTMgJiB3b3JkX3RleHRfaWR4ID49IDIwICYgd29yZF90ZXh0X2lkeCA8PSA1MikpICU+JQogIGZpbHRlcighKHRleHRfaWQgPT0gMyAmIHdvcmRfdGV4dF9pZHggPj0gNDYgJiB3b3JkX3RleHRfaWR4IDw9IDU3KSkgJT4lCiMgZmlsdGVyKHdvcmQueCA9PSB3b3JkKSAjJT4lCmRwbHlyOjpzZWxlY3QoLXdvcmQueCwgLXdvcmQueSkgJT4lCiAgCiMgPT09IFJlbW92ZSBvdXRsaWVycyA+IDNTRAojIGdyb3VwX2J5KG1ldHJpYykgJT4lCiMgICBtdXRhdGUobW90cl9vdXRsaWVyID0gaWZfZWxzZSghIG1ldHJpYyAlaW4lIGMoIkZQUmVnIiwgInNraXAiKSAmIG1vdHJfdmFsdWUgPiAobWVhbihtb3RyX3ZhbHVlKSArIDMgKiBzZChtb3RyX3ZhbHVlKSApLCBULCBGKSkgJT4lCiMgICBmaWx0ZXIobW90cl9vdXRsaWVyID09IEYpICU+JQojICAgbXV0YXRlKGV5ZXRyX291dGxpZXIgPSBpZl9lbHNlKCEgbWV0cmljICVpbiUgYygiRlBSZWciLCAic2tpcCIpICYgZXlldHJfdmFsdWUgPiAobWVhbihleWV0cl92YWx1ZSkgKyAzICogc2QoZXlldHJfdmFsdWUpICksIFQsIEYpKSAlPiUKIyAgIGZpbHRlcihleWV0cl9vdXRsaWVyID09IEYpICU+JQojIHVuZ3JvdXAoKSAlPiUKICAKZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCBjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIikpICMlPiUKIyBkcGx5cjo6c2VsZWN0KC1tb3RyX291dGxpZXIsIC1leWV0cl9vdXRsaWVyKQogIAojIHByb3ZvX2RmCmBgYAoKCiMgQmF5ZXNpYW4gLS0gdXNlIFN0YW4gLS0gbW90ciAmIGV5ZXRyIGNvcnJlbGF0aW9uCmBgYHtyfQpwcmludCgiR2F6ZSBEdXJhdGlvbiIpCmdkX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdhemVfZHVyYXRpb24iKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDEpCiAgKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWVfbG9nID0gbG9nKGV5ZXRyX3ZhbHVlKSwKICAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBsb2cobW90cl92YWx1ZSkpCnByaW50KGNvci50ZXN0KGdkX2RmJGV5ZXRyX3ZhbHVlLCBnZF9kZiRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZ2RfZGYkZXlldHJfdmFsdWVfbG9nLCBnZF9kZiRtb3RyX3ZhbHVlX2xvZykkZXN0aW1hdGUpCiMgVmlldyhnZF9kZikKYGBgCgoKYGBge3J9CmdkX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDEyOjE1KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKICAKYGBgCgoKCmBgYHtyfQojIGNlbnRlciBkYXRhIGFyb3VuZCAwLgoKZ2RfdGVtcCA8LSBnZF9kZltjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JQogICAjIG11dGF0ZShleWV0cl92YWx1ZSA9IGV5ZXRyX3ZhbHVlIC0gbWVhbihleWV0cl92YWx1ZSksCiAgICMgICAgICBtb3RyX3ZhbHVlID0gbW90cl92YWx1ZSAtIG1lYW4obW90cl92YWx1ZSkpICU+JQogIGRhdGEubWF0cml4KCkKCmdkX3RlbXBfbG9nIDwtIGdkX2RmW2MoImV5ZXRyX3ZhbHVlX2xvZyIsICJtb3RyX3ZhbHVlX2xvZyIpXSAlPiUKIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBleWV0cl92YWx1ZV9sb2cgLSBtZWFuKGV5ZXRyX3ZhbHVlX2xvZyksIAogICAgICAgIG1vdHJfdmFsdWVfbG9nID0gbW90cl92YWx1ZV9sb2cgLSBtZWFuKG1vdHJfdmFsdWVfbG9nKSkgJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KGdkX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKIyBQbG90IHRoZSBzZWNvbmQgZGF0YSBtYXRyaXggZ2RfdGVtcF9sb2cKcGxvdChnZF90ZW1wX2xvZywgcGNoID0gMTYsIGNvbCA9ICJyZWQiLAogICAgIG1haW4gPSAiQ2VudGVyZWQgTG9nLVRyYW5zZm9ybWVkIikKCmBgYAoKCgpgYGB7ciwgZXZhbD1GQUxTRX0KZ2RfZGF0YSA9IGxpc3QoeD1nZF90ZW1wLCBOPW5yb3coZ2RfdGVtcCkpCgpmaXRfZ2QgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9jb3JyZWxhdGlvbi5zdGFuIiwgCiAgZGF0YT1nZF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZ2RAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2dkLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9nYXplX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikpCgpgYGAKCmBgYHtyfQpwcmludCgiR28gUGFzdCBUaW1lIikKZ3B0X2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdvX3Bhc3RfdGltZSIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxKSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMSkKICApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBsb2coZXlldHJfdmFsdWUpLAogICAgICAgICBtb3RyX3ZhbHVlX2xvZyA9IGxvZyhtb3RyX3ZhbHVlKSkKcHJpbnQoY29yLnRlc3QoZ3B0X2RmJGV5ZXRyX3ZhbHVlLCBncHRfZGYkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KGdwdF9kZiRleWV0cl92YWx1ZV9sb2csIGdwdF9kZiRtb3RyX3ZhbHVlX2xvZykkZXN0aW1hdGUpCgpncHRfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTI6MTUpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZ3B0X3RlbXAgPC0gZ3B0X2RmW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKCmdwdF90ZW1wX2xvZyA8LSBncHRfZGZbYygiZXlldHJfdmFsdWVfbG9nIiwgIm1vdHJfdmFsdWVfbG9nIildICU+JQogbXV0YXRlKGV5ZXRyX3ZhbHVlX2xvZyA9IGV5ZXRyX3ZhbHVlX2xvZyAtIG1lYW4oZXlldHJfdmFsdWVfbG9nKSwgCiAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBtb3RyX3ZhbHVlX2xvZyAtIG1lYW4obW90cl92YWx1ZV9sb2cpKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBncHRfdGVtcApwbG90KGdwdF90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCiMgUGxvdCB0aGUgc2Vjb25kIGRhdGEgbWF0cml4IGdwdF90ZW1wX2xvZwpwbG90KGdwdF90ZW1wX2xvZywgcGNoID0gMTYsIGNvbCA9ICJyZWQiLAogICAgIG1haW4gPSAiQ2VudGVyZWQgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIGdvIHBhc3QgdGltZSAtLS0tLS0tLS0tCmdwdF9kYXRhID0gbGlzdCh4PWdwdF90ZW1wLCBOPW5yb3coZ3B0X3RlbXApKQpmaXRfZ3B0ID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb24uc3RhbiIsIAogIGRhdGE9Z3B0X2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9ncHRAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2dwdCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfZ29fcGFzdF90aW1lX2Nvcl9kcm9wMHMucmRzIikpCmBgYAoKCmBgYHtyfQpwcmludCgiVG90YWwgRHVyYXRpb24iKQp0ZF9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJ0b3RhbF9kdXJhdGlvbiIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZSA9ICBwbWF4KGV5ZXRyX3ZhbHVlLCAxKSwKICAgICAgICAgbW90cl92YWx1ZSA9IHBtYXgobW90cl92YWx1ZSwgMSkKICApICU+JQogIG11dGF0ZShleWV0cl92YWx1ZV9sb2cgPSBsb2coZXlldHJfdmFsdWUpLAogICAgICAgICBtb3RyX3ZhbHVlX2xvZyA9IGxvZyhtb3RyX3ZhbHVlKSkKcHJpbnQoY29yLnRlc3QodGRfZGYkZXlldHJfdmFsdWUsIHRkX2RmJG1vdHJfdmFsdWUpJGVzdGltYXRlKQpwcmludChjb3IudGVzdCh0ZF9kZiRleWV0cl92YWx1ZV9sb2csIHRkX2RmJG1vdHJfdmFsdWVfbG9nKSRlc3RpbWF0ZSkKCnRkX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDEyOjE1KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCnRkX3RlbXAgPC0gdGRfZGZbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQoKdGRfdGVtcF9sb2cgPC0gdGRfZGZbYygiZXlldHJfdmFsdWVfbG9nIiwgIm1vdHJfdmFsdWVfbG9nIildICU+JQogbXV0YXRlKGV5ZXRyX3ZhbHVlX2xvZyA9IGV5ZXRyX3ZhbHVlX2xvZyAtIG1lYW4oZXlldHJfdmFsdWVfbG9nKSwgCiAgICAgICAgbW90cl92YWx1ZV9sb2cgPSBtb3RyX3ZhbHVlX2xvZyAtIG1lYW4obW90cl92YWx1ZV9sb2cpKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3QodGRfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk5vdCBMb2ctVHJhbnNmb3JtZWQiKQojIFBsb3QgdGhlIHNlY29uZCBkYXRhIG1hdHJpeCB0ZF90ZW1wX2xvZwpwbG90KHRkX3RlbXBfbG9nLCBwY2ggPSAxNiwgY29sID0gInJlZCIsCiAgICAgbWFpbiA9ICJDZW50ZXJlZCBMb2ctVHJhbnNmb3JtZWQiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgdG90YWwgZHVyYXRpb24gLS0tLS0tLS0tLQp0ZF9kYXRhID0gbGlzdCh4PXRkX3RlbXAsIE49bnJvdyh0ZF90ZW1wKSkKZml0X3RkID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb24uc3RhbiIsIAogIGRhdGE9dGRfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X3RkQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF90ZCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKSkKYGBgCgpgYGB7cn0KcHJpbnQoIkZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLiIpCnJlZ19kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA+IDAsIG1vdHJfdmFsdWUgPiAwKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMWUtNSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDFlLTUpKQpwcmludChjb3IudGVzdChyZWdfZGYkZXlldHJfdmFsdWUsIHJlZ19kZiRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKCiMgVmlldyhyZWdfZGYpCnJlZ19kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxMykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpyZWdfdGVtcCA8LSByZWdfZGZbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggdGRfdGVtcApwbG90KHJlZ190ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBGUFJlZyAtLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PXJlZ190ZW1wLCBOPW5yb3cocmVnX3RlbXApKQpmaXRfcmVnID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfbm9ybWFsX3JlZy5zdGFuIiwgCiAgZGF0YT1yZWdfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X3JlZ0BzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfcmVnLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfZHJvcDBzLnJkcyIpKQpgYGAKCiMgcmFuayB0cmFuc2Zvcm1hdGlvbiBmb3IgRlBSZWcKYGBge3IsIGV2YWw9RkFMU0V9CnJlZ19kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogIG11dGF0ZSgKICAgIGV5ZXRyX3ZhbHVlX3JhbmsgPSBpZmVsc2UoZXlldHJfdmFsdWUgPiAwLCByYW5rKGV5ZXRyX3ZhbHVlKSwgTkEpLAogICAgbW90cl92YWx1ZV9yYW5rID0gaWZlbHNlKG1vdHJfdmFsdWUgPiAwLCByYW5rKG1vdHJfdmFsdWUpLCBOQSkKICApICU+JQogIGRyb3BfbmEoKQojICAgbXV0YXRlKAojICAgZXlldHJfdmFsdWVfcmFuayA9IHJhbmsoZXlldHJfdmFsdWUsIHRpZXMubWV0aG9kID0gImF2ZXJhZ2UiKSwKIyAgIG1vdHJfdmFsdWVfcmFuayA9IHJhbmsobW90cl92YWx1ZSwgdGllcy5tZXRob2QgPSAiYXZlcmFnZSIpCiMgKQojIFZpZXcocmVnX2RmKQoKcHJpbnQoY29yLnRlc3QocmVnX2RmJGV5ZXRyX3ZhbHVlX3JhbmssIHJlZ19kZiRtb3RyX3ZhbHVlX3JhbmspJGVzdGltYXRlKQpwcmludChjb3IudGVzdChyZWdfZGYkZXlldHJfdmFsdWVfcmFuaywgcmVnX2RmJG1vdHJfdmFsdWVfcmFuaywgbWV0aG9kID0gImtlbmRhbGwiKSkKCgpyZWdfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTQ6MTUpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKcmVnX3RlbXAgPC0gcmVnX2RmW2MoImV5ZXRyX3ZhbHVlX3JhbmsiLCAibW90cl92YWx1ZV9yYW5rIildICU+JSBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3QocmVnX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJSYW5rIFRyYW5zZm9ybWVkIikKICAKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIEZQUmVnIFJBTkstLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PXJlZ190ZW1wLCBOPW5yb3cocmVnX3RlbXApKQpmaXRfcmVnID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb25fcmFuay5zdGFuIiwgCiAgZGF0YT1yZWdfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9NCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X3JlZ0BzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfcmVnLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfcmFua19kcm9wMHMucmRzIikpCmBgYAoKCmBgYHtyfQpmaXRfZ2QgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9nYXplX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikKZml0X2dwdCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3JfZHJvcDBzLnJkcyIpCmZpdF90ZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX3RvdGFsX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikKZml0X3JlZyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl9kcm9wMHMucmRzIikKZml0X3JlZ19yYW5rID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZXlldHJfRlBSZWdfY29yX3JhbmtfZHJvcDBzLnJkcyIpCgojIG1vZGVscyBmb3IgZHJvcCAwcwojIGZpdF9nZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX2dhemVfZHVyYXRpb25fY29yX2Ryb3Awcy5yZHMiKQojIGZpdF9ncHQgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9nb19wYXN0X3RpbWVfY29yX2Ryb3Awcy5yZHMiKQojIGZpdF90ZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX3RvdGFsX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikKIyBmaXRfcmVnID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL3JhbmtlZF9tb3RyX2V5ZXRyX0ZQUmVnX2Nvci5yZHMiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2dkKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHbyBQYXN0IFRpbWUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9ncHQpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFRvdGFsIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfdGQpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X3JlZykKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIFJBTkstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9yZWdfcmFuaykKCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnM9YygicmhvIiwgIm11IiwgInNpZ21hIiwgIm51IikpCiMgc3Rhbl9kZW5zKGZpdF9nZCwgcGFycz1jKCJyaG8iLCAibXUiLCAic2lnbWEiLCAibnUiKSwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKIyBzdGFuX3Bsb3QoZml0X2dkLCBwYXJzPWMoInJobyIsICJtdSIsICJzaWdtYSIsICJudSIpKQoKIyBHYXplIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X2dkKQpzdGFuX2RlbnMoZml0X2dkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2dkKQoKIyBHbyBQYXN0IFRpbWUKc3Rhbl90cmFjZShmaXRfZ3B0KQpzdGFuX2RlbnMoZml0X2dwdCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9ncHQpCgojIFRvdGFsIER1cmF0aW9uCnN0YW5fdHJhY2UoZml0X3RkKQpzdGFuX2RlbnMoZml0X3RkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X3RkKQoKIyBGUFJlZwpzdGFuX3RyYWNlKGZpdF9yZWcpCnN0YW5fZGVucyhmaXRfcmVnLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X3JlZykKCmBgYAoKYGBge3IsIGZpZy53aWR0aD01LCBmaWcuaGVpZ2h0PTEwLCBldmFsPUZBTFNFfQpwMSA8LSBzdGFuX3RyYWNlKGZpdF9nZCwgcGFycyA9ICdyaG8nLCBpbmNfd2FybXVwID0gRkFMU0UpCnAyIDwtIHN0YW5fZGVucyhmaXRfZ2QsIHBhcnMgPSAncmhvJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDMgPC0gc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnMgPSAnbXVbMV0nLCBpbmNfd2FybXVwID0gRkFMU0UpCnA0IDwtIHN0YW5fZGVucyhmaXRfZ2QsIHBhcnMgPSAnbXVbMV0nLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpwNSA8LSBzdGFuX3RyYWNlKGZpdF9nZCwgcGFycyA9ICdtdVsyXScsIGluY193YXJtdXAgPSBGQUxTRSkKcDYgPC0gc3Rhbl9kZW5zKGZpdF9nZCwgcGFycyA9ICdtdVsyXScsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnA3IDwtIHN0YW5fdHJhY2UoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzFdJywgaW5jX3dhcm11cCA9IEZBTFNFKQpwOCA8LSBzdGFuX2RlbnMoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzFdJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDkgPC0gc3Rhbl90cmFjZShmaXRfZ2QsIHBhcnMgPSAnc2lnbWFbMl0nLCBpbmNfd2FybXVwID0gRkFMU0UpCnAxMCA8LSBzdGFuX2RlbnMoZml0X2dkLCBwYXJzID0gJ3NpZ21hWzJdJywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKcDExIDwtIHN0YW5fdHJhY2UoZml0X2dkLCBwYXJzID0gJ251JywgaW5jX3dhcm11cCA9IEZBTFNFKQpwMTIgPC0gc3Rhbl9kZW5zKGZpdF9nZCwgcGFycyA9ICdudScsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCgoKIyBVc2UgZ3JpZC5hcnJhbmdlKCkgdG8gYXJyYW5nZSB0aGUgcGxvdHMKIyBncmlkLmFycmFuZ2UocDEsIHAyLCBwMywgcDQsIHA1LCBwNiwgcDcsIHA4LCBwOSwgcDEwLCBwMTEsIHAxMiwgbmNvbD0yLCBucm93PTYpCgpgYGAKCgoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdhemUgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19nZCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZ2QsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZ2QpCmNySSA9IHF1YW50aWxlKHJob19nZCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19nZCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2dwdCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfZ3B0LCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2dwdCkKY3JJID0gcXVhbnRpbGUocmhvX2dwdCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19ncHQpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUb3RhbCBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX3RkID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF90ZCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob190ZCkKY3JJID0gcXVhbnRpbGUocmhvX3RkLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX3RkKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKIyByaG9fcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9yZWcsICJyaG9bMSwgMl0iKVtbMV1dKQpyaG9fcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9yZWcsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fcmVnKQpjckkgPSBxdWFudGlsZShyaG9fcmVnLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX3JlZyksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBSQU5LLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQojIHJob19yZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3JlZywgInJob1sxLCAyXSIpW1sxXV0pCnJob19yZWcgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X3JlZ19yYW5rLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX3JlZykKY3JJID0gcXVhbnRpbGUocmhvX3JlZywgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19yZWcpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQpgYGAKCgpgYGB7ciwgZXZhbD1GQUxTRX0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZ2RfcmFuZCA8LSBleHRyYWN0KGZpdF9nZCwgInhfcmFuZCIpW1sxXV0KIyB4X3JhbmRfZmlsdGVyZWQgPC0geF9yYW5kW2FwcGx5KHhfcmFuZCwgMSwgZnVuY3Rpb24oeCkgYWxsKHggPiAwKSksXQojIHhfcmFuZF9maWx0ZXJlZAoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDQwMCksIHlsaW09YygwLCA3MDApLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhnZF9yYW5kWywxXSwgZ2RfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGdkX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShnZF9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZ3B0X3JhbmQgPC0gZXh0cmFjdChmaXRfZ3B0LCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkdvIFBhc3QgVGltZSIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhncHRfcmFuZFssMV0sIGdwdF9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZ3B0X3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZ3B0X3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UoZ3B0X3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnRkX3JhbmQgPC0gZXh0cmFjdChmaXRfdGQsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDEyMDApLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiVG90YWwgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHModGRfcmFuZFssMV0sIHRkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyh0ZF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKHRkX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UodGRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9yZWcsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgMSksIHlsaW09YygwLCAxKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUiLCB5bGFiID0gIk1vVFIgdmFsdWUiLCBtYWluID0gIkZQUmVnIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKHJlZ19yYW5kWywxXSwgcmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhyZWdfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgoKYGBgCgojIG1vZGVsIG1vdHIgZXlldHIgRlBSZWcgY29ycmVsYXRpb24gKGV5ZXRyIDwgMC4zKQpgYGB7cn0KcHJpbnQoIkZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLiBhbGwgYW5kICA8IDAuMyIpCnJlZ19kZl9hbGwgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIGZpbHRlcihleWV0cl92YWx1ZSA+IDAsIG1vdHJfdmFsdWUgPiAwKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMWUtNSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDFlLTUpKQoKcmVnX2RmX2xvd19kcm9wMCA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSAKICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZSA+IDAsIG1vdHJfdmFsdWUgPiAwKSAlPiUKICBtdXRhdGUoZXlldHJfdmFsdWUgPSAgcG1heChleWV0cl92YWx1ZSwgMWUtNSksCiAgICAgICAgIG1vdHJfdmFsdWUgPSBwbWF4KG1vdHJfdmFsdWUsIDFlLTUpKSAlPiUKICBmaWx0ZXIoZXlldHJfdmFsdWUgPCAwLjMpCgpyZWdfZGZfbG93ID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlIDwgMC4zKQogICMgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gZXhwKGV5ZXRyX3ZhbHVlKSwKICAgICAgICAgIyBtb3RyX3ZhbHVlID0gZXhwKG1vdHJfdmFsdWUpCiAgICAgICAgICMgKQojIFZpZXcocmVnX2RmKQoKcHJpbnQoY29yLnRlc3QocmVnX2RmX2FsbCRleWV0cl92YWx1ZSwgcmVnX2RmX2FsbCRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2FsbCRleWV0cl92YWx1ZSwgcmVnX2RmX2FsbCRtb3RyX3ZhbHVlKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChyZWdfZGZfbG93JGV5ZXRyX3ZhbHVlLCByZWdfZGZfbG93JG1vdHJfdmFsdWUpJGVzdGltYXRlKQpwcmludChjb3IudGVzdChyZWdfZGZfbG93JGV5ZXRyX3ZhbHVlLCByZWdfZGZfbG93JG1vdHJfdmFsdWUpJHAudmFsdWUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9sb3dfZHJvcDAkZXlldHJfdmFsdWUsIHJlZ19kZl9sb3dfZHJvcDAkbW90cl92YWx1ZSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9sb3dfZHJvcDAkZXlldHJfdmFsdWUsIHJlZ19kZl9sb3dfZHJvcDAkbW90cl92YWx1ZSkkcC52YWx1ZSkKCiMgVmlldyhyZWdfZGYpCnJlZ19kZl9sb3cgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgMTI6MTMpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKcmVnX3RlbXBfYWxsIDwtIHJlZ19kZl9hbGxbYygiZXlldHJfdmFsdWUiLCAibW90cl92YWx1ZSIpXSAlPiUgZGF0YS5tYXRyaXgoKQpyZWdfdGVtcF9sb3cgPC0gcmVnX2RmX2xvd1tjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCnJlZ190ZW1wX2xvd19kcm9wMCA8LSByZWdfZGZfbG93X2Ryb3AwW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IHRkX3RlbXAKcGxvdChyZWdfdGVtcF9sb3csIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIEZQUmVnIDwgMC4zIC0tLS0tLS0tLS0KcmVnX2RhdGEgPSBsaXN0KHg9cmVnX3RlbXBfYWxsLCBOPW5yb3cocmVnX3RlbXBfYWxsKSkKZml0X3JlZyA9IHN0YW4oCiAgIyBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfYmV0YV9jb3JyZWxhdGlvbl9yZWcuc3RhbiIsIAogIGZpbGUgPSAic3Rhbl9tb2RlbHMvYml2YXJpYXRlX25vcm1hbF9yZWcuc3RhbiIsCiAgZGF0YT1yZWdfZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9NCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X3JlZ0BzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfcmVnLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9leWV0cl9GUFJlZ19jb3JfYWxsX2RhdGFfZHJvcDBzLnJkcyIpKQpgYGAKCgojIG1vZGVsIG1vdHIgZXlldHIgRlBSZWcgY29ycmVsYXRpb24gKGV5ZXRyID49IDAuMykKYGBge3J9CnByaW50KCJGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4gPj0gMC4zIikKcmVnX2RmX2hpZ2hfZHJvcDAgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgCiAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlID49IDAuMykKCnJlZ19kZl9oaWdoID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gIkZQUmVnIikgJT4lIAogIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBmaWx0ZXIoZXlldHJfdmFsdWUgPiAwLCBtb3RyX3ZhbHVlID4gMCkgJT4lCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlID0gIHBtYXgoZXlldHJfdmFsdWUsIDFlLTUpLAogICAgICAgICBtb3RyX3ZhbHVlID0gcG1heChtb3RyX3ZhbHVlLCAxZS01KSkgJT4lCiAgZmlsdGVyKGV5ZXRyX3ZhbHVlID49IDAuMykKICAjIG11dGF0ZShleWV0cl92YWx1ZSA9IGV4cChleWV0cl92YWx1ZSksCiAgICAgICAgICMgbW90cl92YWx1ZSA9IGV4cChtb3RyX3ZhbHVlKQogICAgICAgICAjICkKIyBWaWV3KHJlZ19kZikKCnByaW50KGNvci50ZXN0KHJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlLCByZWdfZGZfaGlnaCRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2hpZ2gkZXlldHJfdmFsdWUsIHJlZ19kZl9oaWdoJG1vdHJfdmFsdWUpJHAudmFsdWUpCnByaW50KGNvci50ZXN0KHJlZ19kZl9oaWdoX2Ryb3AwJGV5ZXRyX3ZhbHVlLCByZWdfZGZfaGlnaF9kcm9wMCRtb3RyX3ZhbHVlKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QocmVnX2RmX2hpZ2hfZHJvcDAkZXlldHJfdmFsdWUsIHJlZ19kZl9oaWdoX2Ryb3AwJG1vdHJfdmFsdWUpJHAudmFsdWUpCgojIFZpZXcocmVnX2RmKQpyZWdfZGZfaGlnaCAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCAxMjoxMykgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpyZWdfdGVtcF9oaWdoIDwtIHJlZ19kZl9oaWdoW2MoImV5ZXRyX3ZhbHVlIiwgIm1vdHJfdmFsdWUiKV0gJT4lIGRhdGEubWF0cml4KCkKcmVnX3RlbXBfaGlnaF9kcm9wMCA8LSByZWdfZGZfaGlnaF9kcm9wMFtjKCJleWV0cl92YWx1ZSIsICJtb3RyX3ZhbHVlIildICU+JSBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAzKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCB0ZF90ZW1wCnBsb3QocmVnX3RlbXBfYWxsLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgbm90IGxvZ2dlZCBhbGwgZGF0YSIpCnBsb3QocmVnX3RlbXBfbG93LCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgbm90IGxvZ2dlZCBleWV0ciA8IDAuMyAiKQpwbG90KHJlZ190ZW1wX2hpZ2gsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJGUFJlZyBub3QgbG9nZ2VkIGV5ZXRyID49IDAuMyIpCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiMgLS0tLS0tLWZpdCBtb2RlbCBGUFJlZyA+PSAwLjMgLS0tLS0tLS0tLQpyZWdfZGF0YSA9IGxpc3QoeD1yZWdfdGVtcF9oaWdoX2Ryb3AwLCBOPW5yb3cocmVnX3RlbXBfaGlnaF9kcm9wMCkpCmZpdF9yZWcgPSBzdGFuKAogICMgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2JldGFfY29ycmVsYXRpb25fcmVnLnN0YW4iLCAKICBmaWxlID0gInN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9ub3JtYWxfcmVnLnN0YW4iLAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTQsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi8vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl8wMy0xX2Ryb3Awcy5yZHMiKSkKYGBgCgoKCmBgYHtyfQpmaXRfbXJlZ19hbGwgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb25fMjAyMy9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKQpmaXRfbXJlZ19hbGxfZHJvcDAgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb25fMjAyMy9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YV9kcm9wMHMucmRzIikKZml0X21yZWdfbG93ID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfMDAtMDMucmRzIikKZml0X21yZWdfbG93X2Ryb3AwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uXzIwMjMvbW90cl9leWV0cl9GUFJlZ19jb3JfMDAtMDNfZHJvcDBzLnJkcyIpCmZpdF9tcmVnX2hpZ2ggPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb25fMjAyMy9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl8wMy0xLnJkcyIpCmZpdF9tcmVnX2hpZ2hfZHJvcDAgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb25fMjAyMy9tb3RyX2V5ZXRyX0ZQUmVnX2Nvcl8wMy0xX2Ryb3Awcy5yZHMiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIGFsbCBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X21yZWdfYWxsKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4gYWxsIGRhdGEgbm8gMHMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tcmVnX2FsbF9kcm9wMCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuPCAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tcmVnX2xvdykKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuPCAwLjMgbm8gMHMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tcmVnX2xvd19kcm9wMCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuPj0gMC4zLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXJlZ19oaWdoKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4+PSAwLjMgbm8gMHMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tcmVnX2hpZ2hfZHJvcDApCmBgYAoKYGBge3J9CiMgIyBGUFJlZyBhbGwgZGF0YQojIHN0YW5fdHJhY2UoZml0X21yZWdfYWxsKQojIHN0YW5fZGVucyhmaXRfbXJlZ19hbGwsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCiMgc3Rhbl9wbG90KGZpdF9tcmVnX2FsbCkKCiMgc3Rhbl90cmFjZShmaXRfbXJlZ19hbGxfZHJvcDApCiMgc3Rhbl9kZW5zKGZpdF9tcmVnX2FsbF9kcm9wMCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKIyBzdGFuX3Bsb3QoZml0X21yZWdfYWxsX2Ryb3AwKQoKIyAjIEZQUmVnIDwgMC4zCiMgc3Rhbl90cmFjZShmaXRfbXJlZ19sb3cpCiMgc3Rhbl9kZW5zKGZpdF9tcmVnX2xvdywgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKIyBzdGFuX3Bsb3QoZml0X21yZWdfbG93KQojIAojIHN0YW5fdHJhY2UoZml0X21yZWdfbG93X2Ryb3AwKQojIHN0YW5fZGVucyhmaXRfbXJlZ19sb3dfZHJvcDAsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCiMgc3Rhbl9wbG90KGZpdF9tcmVnX2xvd19kcm9wMCkKCiMgRlBSZWcgPiAwLjMKc3Rhbl90cmFjZShmaXRfbXJlZ19oaWdoKQpzdGFuX2RlbnMoZml0X21yZWdfaGlnaCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9tcmVnX2hpZ2gpCgpzdGFuX3RyYWNlKGZpdF9tcmVnX2hpZ2hfZHJvcDApCnN0YW5fZGVucyhmaXRfbXJlZ19oaWdoX2Ryb3AwLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21yZWdfaGlnaF9kcm9wMCkKYGBgCgpgYGB7cn0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIGFsbCBkYXRhLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19hbGwgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21yZWdfYWxsLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21yZWdfYWxsKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19hbGwsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbXJlZ19hbGwpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gYWxsIGRhdGEgbm8gMHMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tcmVnX2FsbF9kcm9wMCA9IGFzLm51bWVyaWMoZXh0cmFjdChmaXRfbXJlZ19hbGxfZHJvcDAsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fbXJlZ19hbGxfZHJvcDApCmNySSA9IHF1YW50aWxlKHJob19tcmVnX2FsbF9kcm9wMCwgYyguMDI1LCAuOTc1KSkKaHBkOTkgPSBIUERpbnRlcnZhbChhcy5tY21jKHJob19tcmVnX2FsbF9kcm9wMCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21yZWdfbG93ID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2xvdywgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tcmVnX2xvdykKY3JJID0gcXVhbnRpbGUocmhvX21yZWdfbG93LCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfbG93KSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIDwgMC4zIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19sb3dfZHJvcDAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21yZWdfbG93X2Ryb3AwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21yZWdfbG93X2Ryb3AwKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19sb3dfZHJvcDAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbXJlZ19sb3dfZHJvcDApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gPj0gMC4zLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbXJlZ19oaWdoID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fbXJlZ19oaWdoKQpjckkgPSBxdWFudGlsZShyaG9fbXJlZ19oaWdoLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21yZWdfaGlnaCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA+PSAwLjMgbm8gMHMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tcmVnX2hpZ2hfZHJvcDAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21yZWdfaGlnaF9kcm9wMCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tcmVnX2hpZ2hfZHJvcDApCmNySSA9IHF1YW50aWxlKHJob19tcmVnX2hpZ2hfZHJvcDAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbXJlZ19oaWdoX2Ryb3AwKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gYWxsIGRhdGEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptYWxscmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfbXJlZ19hbGwsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWFsbHJlZ19yYW5kWywxXSwgbWFsbHJlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXBfYWxsLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1hbGxyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtYWxscmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIGFsbCBkYXRhIG5vIDBzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptYWxscmVnX3JhbmRfZHJvcDAgPC0gZXh0cmFjdChmaXRfbXJlZ19hbGxfZHJvcDAsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWFsbHJlZ19yYW5kX2Ryb3AwWywxXSwgbWFsbHJlZ19yYW5kX2Ryb3AwWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXBfYWxsLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1hbGxyZWdfcmFuZF9kcm9wMCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtYWxscmVnX3JhbmRfZHJvcDAsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIDwgMC4zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWxvd3JlZ19yYW5kIDwtIGV4dHJhY3QoZml0X21yZWdfbG93LCAieF9yYW5kIilbWzFdXQpwcmludChtbG93cmVnX3JhbmQpCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMobWxvd3JlZ19yYW5kWywxXSwgbWxvd3JlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMocmVnX3RlbXBfbG93LCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1sb3dyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtbG93cmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIDwgMC4zIG5vIDBzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWxvd3JlZ19yYW5kX2Ryb3AwIDwtIGV4dHJhY3QoZml0X21yZWdfbG93X2Ryb3AwLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtbG93cmVnX3JhbmRfZHJvcDBbLDFdLCBtbG93cmVnX3JhbmRfZHJvcDBbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhyZWdfdGVtcF9sb3dfZHJvcDAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UobWxvd3JlZ19yYW5kX2Ryb3AwLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKG1sb3dyZWdfcmFuZF9kcm9wMCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gPj0gMC4zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKbWhpZ2hyZWdfcmFuZF9zYW1wbGVzIDwtIGV4dHJhY3QoZml0X21yZWdfaGlnaCwgInhfcmFuZCIpW1sxXV0KIyBwcmludChtaGlnaHJlZ19yYW5kX3NhbXBsZXMpCnNlbGVjdGVkX2luZGljZXMgPC0gc2FtcGxlKDE6bnJvdyhtaGlnaHJlZ19yYW5kX3NhbXBsZXMpLCA5MDApCm1oaWdocmVnX3JhbmQgPC0gbWhpZ2hyZWdfcmFuZF9zYW1wbGVzW3NlbGVjdGVkX2luZGljZXMsIF0KIyBtaGlnaHJlZ19yYW5kIDwtIGV4dHJhY3QoZml0X21yZWdfaGlnaCwgInhfcmFuZCIpW1sxXV0KIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtaGlnaHJlZ19yYW5kWywxXSwgbWhpZ2hyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2hpZ2gsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UobWhpZ2hyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtaGlnaHJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCiMgcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMyBubyAwcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1oaWdocmVnX3JhbmRfZHJvcDBfc2FtcGxlcyA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2hfZHJvcDAsICJ4X3JhbmQiKVtbMV1dCnNlbGVjdGVkX2luZGljZXMgPC0gc2FtcGxlKDE6bnJvdyhtaGlnaHJlZ19yYW5kX2Ryb3AwX3NhbXBsZXMpLCA5MDApCm1oaWdocmVnX3JhbmRfZHJvcDAgPC0gbWhpZ2hyZWdfcmFuZF9kcm9wMF9zYW1wbGVzW3NlbGVjdGVkX2luZGljZXMsIF0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yCnBvaW50cyhtaGlnaHJlZ19yYW5kX2Ryb3AwWywxXSwgbWhpZ2hyZWdfcmFuZF9kcm9wMFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKHJlZ190ZW1wX2hpZ2hfZHJvcDAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvcgpkYXRhRWxsaXBzZShtaGlnaHJlZ19yYW5kX2Ryb3AwLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKG1oaWdocmVnX3JhbmRfZHJvcDAsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCgoKIyBtb2RlbCBleWUgdHJhY2tpbmcgdG8gZXllIHRyYWNraW5nIGNvcnJlbGF0aW9uCmBgYHtyfQoKcHJpbnQoIkdhemUgRHVyYXRpb24iKQojIFZpZXcocHJvdm9fZXlldHJfZ3JvdXBlZF9kZikKCmVnZF9kZiA9IHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdhemVfZHVyYXRpb24iKSAlPiUgI2dyb3VwX2J5KHRleHRfaWQsIG1ldHJpYywgbWVhc3VyZSkgJT4lCiAgIyBzdW1tYXJpemUodmFsdWUgPSBtZWFuKHZhbHVlLCBuYS5ybSA9IFRSVUUpLCAuZ3JvdXBzID0gJ2Ryb3AnKSAlPiUKICAgIGZpbHRlcih0ZXh0X2lkICE9IDE4KSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxKSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMSkKICApIApwcmludChjb3IudGVzdChlZ2RfZGYkZXlldHJfdmFsdWVfMSwgZWdkX2RmJGV5ZXRyX3ZhbHVlXzIpJGVzdGltYXRlKQoKIyBWaWV3KGVnZF9kZikKCmVnZF9kZiAlPiUgCiAgZ2F0aGVyKG1lYXN1cmUsIHZhbHVlLCA1OjYpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKZWdkX3RlbXAgPC0gZWdkX2RmW2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWdkX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJOb3QgTG9nLVRyYW5zZm9ybWVkIikKCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CmVnZF9kYXRhID0gbGlzdCh4PWVnZF90ZW1wLCBOPW5yb3coZWdkX3RlbXApKQoKZml0X2VnZCA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWVnZF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZWdkQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9lZ2QsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9jb3JfYml2YXJpYXRlL2V5ZXRyX2V5ZXRyX2dhemVfZHVyYXRpb25fY29yLnJkcyIpKQoKYGBgCgpgYGB7cn0KcHJpbnQoIkdvIFBhc3QgVGltZSIpCgplZ3B0X2RmID0gcHJvdm9fZXlldHJfZ3JvdXBlZF9kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiZ29fcGFzdF90aW1lIikgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lCiAgZmlsdGVyKHRleHRfaWQgIT0gMTgpICU+JQogICAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWVfMSA9ICBwbWF4KHZhbHVlXzEsIDEpLAogICAgICAgICBleWV0cl92YWx1ZV8yID0gcG1heCh2YWx1ZV8yLCAxKQogICkgCnByaW50KGNvci50ZXN0KGVncHRfZGYkZXlldHJfdmFsdWVfMSwgZWdwdF9kZiRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKCiMgVmlldyhlZ2RfZGYpCgplZ3B0X2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDU6NikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgplZ3B0X3RlbXAgPC0gZWdwdF9kZltjKCJleWV0cl92YWx1ZV8xIiwgImV5ZXRyX3ZhbHVlXzIiKV0gJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KGVncHRfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk5vdCBMb2ctVHJhbnNmb3JtZWQiKQpgYGAKCmBgYHtyLCBldmFsPUZBTFNFfQplZ3B0X2RhdGEgPSBsaXN0KHg9ZWdwdF90ZW1wLCBOPW5yb3coZWdwdF90ZW1wKSkKCmZpdF9lZ3B0ID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb24uc3RhbiIsIAogIGRhdGE9ZWdwdF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfZWdwdEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZWdwdCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX2dvX3Bhc3RfdGltZV9jb3IucmRzIikpCgpgYGAKCgpgYGB7cn0KcHJpbnQoIlRvdGFsIER1cmF0aW9uIikKCmV0ZF9kZiA9IHByb3ZvX2V5ZXRyX2dyb3VwZWRfZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gInRvdGFsX2R1cmF0aW9uIikgJT4lICNncm91cF9ieSh0ZXh0X2lkLCBtZXRyaWMsIG1lYXN1cmUpICU+JQogICMgc3VtbWFyaXplKHZhbHVlID0gbWVhbih2YWx1ZSwgbmEucm0gPSBUUlVFKSwgLmdyb3VwcyA9ICdkcm9wJykgJT4lCiAgZmlsdGVyKHRleHRfaWQgIT0gMTgpICU+JQogICAgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKSAlPiUKICAjIHNtb290aGluZywgaWYgaW5jbHVkZXMgMHMKICBtdXRhdGUoZXlldHJfdmFsdWVfMSA9ICBwbWF4KHZhbHVlXzEsIDEpLAogICAgICAgICBleWV0cl92YWx1ZV8yID0gcG1heCh2YWx1ZV8yLCAxKQogICkgCnByaW50KGNvci50ZXN0KGV0ZF9kZiRleWV0cl92YWx1ZV8xLCBldGRfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCgojIFZpZXcoZWdkX2RmKQoKZXRkX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDU6NikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgpldGRfdGVtcCA8LSBldGRfZGZbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChldGRfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIlRvdGFsIER1cmF0aW9uIE5vdCBMb2ctVHJhbnNmb3JtZWQiKQpgYGAKCgpgYGB7ciwgZXZhbD1GQUxTRX0KZXRkX2RhdGEgPSBsaXN0KHg9ZXRkX3RlbXAsIE49bnJvdyhldGRfdGVtcCkpCgpmaXRfZXRkID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9iaXZhcmlhdGVfY29ycmVsYXRpb24uc3RhbiIsIAogIGRhdGE9ZXRkX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2V0ZEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZXRkLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfdG90YWxfZHVyYXRpb25fY29yLnJkcyIpKQpgYGAKCgpgYGB7cn0KcHJpbnQoIkZpc3J0IFBhc3MgUmVncmVzc2lvbiBQcm9iLiIpCgplcmVnX2RmID0gcHJvdm9fZXlldHJfZ3JvdXBlZF9kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgZGlzdGluY3QoKSAlPiUgI2dyb3VwX2J5KHRleHRfaWQsIG1ldHJpYywgbWVhc3VyZSkgJT4lCiAgIyBzdW1tYXJpemUodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgIyBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICBmaWx0ZXIodGV4dF9pZCAhPSAxOCkgJT4lCiAgICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogIAogICMgPT09PSBmb3Igbm9ybWFsIGRhdGEgZHJvcDBzID09PT0KICAjIGZpbHRlcih2YWx1ZV8xID4gMCwgdmFsdWVfMiA+IDApICU+JQogICMgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAjICAgICAgICBleWV0cl92YWx1ZV8yID0gcG1heCh2YWx1ZV8yLCAxZS01KQogICMgKQogIAogICMgPT09PSBmb3IgcmFua2luZyB0aGUgZGF0YSBkcm9wMHMgPT09PQogICAgbXV0YXRlKAogICAgZXlldHJfdmFsdWVfMSA9IGlmZWxzZSh2YWx1ZV8xID4gMCwgcmFuayh2YWx1ZV8xKSwgTkEpLAogICAgZXlldHJfdmFsdWVfMiA9IGlmZWxzZSh2YWx1ZV8yID4gMCwgcmFuayh2YWx1ZV8yKSwgTkEpCiAgKSAlPiUKICBkcm9wX25hKCkKCiAgIyA9PT09IGZvciByYW5raW5nIHRoZSBkYXRhIHcvIDBzID09PT0KICAjICAgbXV0YXRlKAogICMgICBleWV0cl92YWx1ZV8xID0gcmFuayh2YWx1ZV8xLCB0aWVzLm1ldGhvZCA9ICJhdmVyYWdlIiksCiAgIyAgIGV5ZXRyX3ZhbHVlXzIgPSByYW5rKHZhbHVlXzIsIHRpZXMubWV0aG9kID0gImF2ZXJhZ2UiKQogICMgKQoKCnByaW50KGNvci50ZXN0KGVyZWdfZGYkZXlldHJfdmFsdWVfMSwgZXJlZ19kZiRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKCiMgVmlldyhlZ2RfZGYpCgplcmVnX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIDU6NikgJT4lCiAgZ2dwbG90KGFlcyh4ID0gdmFsdWUpKSArCiAgZ2VvbV9kZW5zaXR5KCkgKwogIGZhY2V0X3dyYXAofm1lYXN1cmUsIHNjYWxlcyA9ICJmcmVlIikgKwogIHRoZW1lX2J3KCkgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpCgplcmVnX3RlbXAgPC0gZXJlZ19kZltjKCJleWV0cl92YWx1ZV8xIiwgImV5ZXRyX3ZhbHVlXzIiKV0gJT4lCiAgZHJvcF9uYSgpICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChlcmVnX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJGUFJlZyBOb3QgTG9nLVRyYW5zZm9ybWVkIikKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyAtLS0tLS0tZml0IG1vZGVsIEZQUmVnIC0tLS0tLS0tLS0KCiMgVmlldyhlcmVnX3RlbXApCmVyZWdfZGF0YSA9IGxpc3QoeD1lcmVnX3RlbXAsIE49bnJvdyhlcmVnX3RlbXApKQpmaXRfZXJlZyA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2NvcnJlbGF0aW9uX3Jhbmsuc3RhbiIsIAogIGRhdGE9ZXJlZ19kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9lcmVnQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9lcmVnLCBmaWxlID0gcGFzdGUwKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfRlBSZWdfY29yX3JhbmtfZHJvcDBzLnJkcyIpKQpgYGAKCgpgYGB7cn0KZml0X2VnZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9nYXplX2R1cmF0aW9uX2Nvcl9kcm9wMHMucmRzIikKZml0X2VncHQgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfZ29fcGFzdF90aW1lX2Nvcl9kcm9wMHMucmRzIikKZml0X2V0ZCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl90b3RhbF9kdXJhdGlvbl9jb3JfZHJvcDBzLnJkcyIpCmZpdF9lcmVnID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9kcm9wMHMucmRzIikKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VnZCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR28gUGFzdCBUaW1lLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfZWdwdCkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gVG90YWwgRHVyYXRpb24tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9ldGQpCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBQcm9iLi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWcpCmBgYAoKCmBgYHtyLCBldmFsPUZBTFNFfQojIHN0YW5fdHJhY2UoZml0X2VnZCwgcGFycz1jKCJyaG8iLCAibXUiLCAic2lnbWEiLCAibnUiKSkKIyBzdGFuX2RlbnMoZml0X2VnZCwgcGFycz1jKCJyaG8iLCAibXUiLCAic2lnbWEiLCAibnUiKSwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKIyBzdGFuX3Bsb3QoZml0X2VnZCwgcGFycz1jKCJyaG8iLCAibXUiLCAic2lnbWEiLCAibnUiKSkKCiMgR2F6ZSBEdXJhdGlvbgpzdGFuX3RyYWNlKGZpdF9lZ2QpCnN0YW5fZGVucyhmaXRfZWdkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VnZCkKCiMgR28gUGFzdCBUaW1lCnN0YW5fdHJhY2UoZml0X2VncHQpCnN0YW5fZGVucyhmaXRfZWdwdCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lZ3B0KQoKIyBUb3RhbCBEdXJhdGlvbgpzdGFuX3RyYWNlKGZpdF9ldGQpCnN0YW5fZGVucyhmaXRfZXRkLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2V0ZCkKCiMgRlBSZWcKc3Rhbl90cmFjZShmaXRfZXJlZykKc3Rhbl9kZW5zKGZpdF9lcmVnLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWcpCmBgYAoKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHYXplIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZWdkID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lZ2QsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZWdkKQpjckkgPSBxdWFudGlsZShyaG9fZWdkLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VnZCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEdvIFBhc3QgVGltZS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VncHQgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VncHQsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZWdwdCkKY3JJID0gcXVhbnRpbGUocmhvX2VncHQsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZWdwdCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIFRvdGFsIER1cmF0aW9uLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZXRkID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9ldGQsICJyaG8iKVtbMV1dKQptZWFuID0gbWVhbihyaG9fZXRkKQpjckkgPSBxdWFudGlsZShyaG9fZXRkLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2V0ZCksIHByb2I9MC45NSkKY2F0KCJNZWFuOiAiLCBtZWFuLCAiXG5IUEQ6IFsiLCBocGQ5OVssImxvd2VyIl0sICIsICIsIGhwZDk5WywidXBwZXIiXSwgIl0iLCBzZXA9IiIsICJcbmNySTogWyIsIGNySVsxXSwgIiwgIiwgY3JJWzJdLCAiXVxuIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lcmVnID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VyZWcpCmNySSA9IHF1YW50aWxlKHJob19lcmVnLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWcpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQpgYGAKCgpgYGB7ciwgZXZhbD1GQUxTRX0KcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gR2F6ZSBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWdkX3JhbmQgPC0gZXh0cmFjdChmaXRfZWdkLCAieF9yYW5kIilbWzFdXQojIHhfcmFuZF9maWx0ZXJlZCA8LSB4X3JhbmRbYXBwbHkoeF9yYW5kLCAxLCBmdW5jdGlvbih4KSBhbGwoeCA+IDApKSxdCiMgeF9yYW5kX2ZpbHRlcmVkCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgNDAwKSwgeWxpbT1jKDAsIDcwMCksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDEiLCB5bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSAyIiwgbWFpbiA9ICJHYXplIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGVnZF9yYW5kWywxXSwgZWdkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlZ2RfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlZ2RfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBHbyBQYXN0IFRpbWUtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVncHRfcmFuZCA8LSBleHRyYWN0KGZpdF9lZ3B0LCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMSIsIHlsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDIiLCBtYWluID0gIkdvIFBhc3QgVGltZSIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlZ3B0X3JhbmRbLDFdLCBlZ3B0X3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlZ3B0X3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZWdwdF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVncHRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBUb3RhbCBEdXJhdGlvbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZXRkX3JhbmQgPC0gZXh0cmFjdChmaXRfZXRkLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMjAwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMSIsIHlsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIDIiLCBtYWluID0gIlRvdGFsIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGV0ZF9yYW5kWywxXSwgZXRkX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhldGRfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShldGRfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShldGRfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQplcmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfZXJlZywgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSAxIiwgeWxhYiA9ICJFeWUgdHJhY2tpbmcgdmFsdWUgMiIsIG1haW4gPSAiRmlyc3QgUGFzcyBSZWdyZXNzaW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKGVyZWdfcmFuZFssMV0sIGVyZWdfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGVyZWdfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlcmVnX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UoZXJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKYGBgCgoKIyBCYXllc2lhbiAtLSBjb3JyZWxhdGlvbiBiZXR3ZWVuIE1vVFIgYW5kIHdvcmQgbGV2ZWwgc3RhdGlzdGljcwpgYGB7cn0KcHJpbnQoIkxvZyBGcmVxdWVuY3kiKQpzdGF0c19jb3JfZGYgPSBwcm92b19kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiZ2F6ZV9kdXJhdGlvbiIpICU+JSBzcHJlYWQobWVhc3VyZSwgdmFsdWUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRtb3RyX3ZhbHVlLCBzdGF0c19jb3JfZGYkZnJlcSkkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRleWV0cl92YWx1ZSwgc3RhdHNfY29yX2RmJGZyZXEpJGVzdGltYXRlKQoKIyBWaWV3KHN0YXRzX2Nvcl9kZikKc3RhdHNfY29yX2RmICU+JSAKICBnYXRoZXIobWVhc3VyZSwgdmFsdWUsIGMoNywgMTMpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCm1mcmVxX3RlbXAgPC0gc3RhdHNfY29yX2RmW2MoIm1vdHJfdmFsdWUiLCAiZnJlcSIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCmVmcmVxX3RlbXAgPC0gc3RhdHNfY29yX2RmW2MoImV5ZXRyX3ZhbHVlIiwgImZyZXEiKV0gJT4lCiAgZGF0YS5tYXRyaXgoKQoKIyBTZXQgdXAgdGhlIHBsb3R0aW5nIGFyZWEgd2l0aCB0d28gc2lkZS1ieS1zaWRlIHBsb3RzCnBhcihtZnJvdyA9IGMoMSwgMikpCiMgUGxvdCB0aGUgZmlyc3QgZGF0YSBtYXRyaXggZ2RfdGVtcApwbG90KG1mcmVxX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJNb1RSIFJUcyBhbmQgV29yZCBGcmVxdWVuY3kiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWZyZXFfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkV5ZVRSIFJUcyBhbmQgV29yZCBGcmVxdWVuY3kiKQoKYGBgCiMgbW90ciAmIGZyZXF1ZW5jeQpgYGB7ciwgZXZhbD1GQUxTRX0KbWZyZXFfZGF0YSA9IGxpc3QoeD1tZnJlcV90ZW1wLCBOPW5yb3cobWZyZXFfdGVtcCkpCgpmaXRfbWZyZXEgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPW1mcmVxX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X21mcmVxQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9tZnJlcSwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfZnJlcV9jb3IucmRzIikpCmBgYAoKIyBleWV0ciAmIGZyZXF1ZW5jeQpgYGB7ciwgZXZhbD1GQUxTRX0KZWZyZXFfZGF0YSA9IGxpc3QoeD1lZnJlcV90ZW1wLCBOPW5yb3coZWZyZXFfdGVtcCkpCgpmaXRfZWZyZXEgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPWVmcmVxX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VmcmVxQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9lZnJlcSwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2ZyZXFfY29yLnJkcyIpKQpgYGAKCmBgYHtyfQpwcmludCgiTGVuZ3RoIikKc3RhdHNfY29yX2RmID0gcHJvdm9fZGYgJT4lIGZpbHRlcihtZXRyaWMgPT0gImdhemVfZHVyYXRpb24iKSAlPiUgc3ByZWFkKG1lYXN1cmUsIHZhbHVlKQpwcmludChjb3IudGVzdChzdGF0c19jb3JfZGYkbW90cl92YWx1ZSwgc3RhdHNfY29yX2RmJGxlbikkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KHN0YXRzX2Nvcl9kZiRleWV0cl92YWx1ZSwgc3RhdHNfY29yX2RmJGxlbikkZXN0aW1hdGUpCgojIFZpZXcoc3RhdHNfY29yX2RmKQpzdGF0c19jb3JfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYyg5LCAxMykpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKbWxlbl90ZW1wIDwtIHN0YXRzX2Nvcl9kZltjKCJtb3RyX3ZhbHVlIiwgImxlbiIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCmVsZW5fdGVtcCA8LSBzdGF0c19jb3JfZGZbYygiZXlldHJfdmFsdWUiLCAibGVuIildICU+JQogIGRhdGEubWF0cml4KCkKCiMgU2V0IHVwIHRoZSBwbG90dGluZyBhcmVhIHdpdGggdHdvIHNpZGUtYnktc2lkZSBwbG90cwpwYXIobWZyb3cgPSBjKDEsIDIpKQojIFBsb3QgdGhlIGZpcnN0IGRhdGEgbWF0cml4IGdkX3RlbXAKcGxvdChtbGVuX3RlbXAsIHBjaCA9IDE2LCBjb2wgPSAiYmx1ZSIsCiAgICAgbWFpbiA9ICJNb1RSIFJUcyBhbmQgV29yZCBMZW5ndGgiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZWxlbl90ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRXllVFIgUlRzIGFuZCBXb3JkIExlbmd0aCIpCmBgYAoKIyBtb3RyICYgbGVuZ3RoCmBgYHtyLCBldmFsPUZBTFNFfQptbGVuX2RhdGEgPSBsaXN0KHg9bWxlbl90ZW1wLCBOPW5yb3cobWxlbl90ZW1wKSkKCmZpdF9tbGVuID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9zdGF0c19jb3JyZWxhdGlvbl9sZW5fbm9ybWFsLnN0YW4iLCAKICBkYXRhPW1sZW5fZGF0YSwgCiAgaXRlcj00MDAwLCAKICBjaGFpbnM9NCwgCiAgY29yZXM9OCwKICBzZWVkPTQ0NCwKICAjIGNvbnRyb2w9bGlzdChhZGFwdF9kZWx0YT0wLjk5KSwgCiAgIyB2ZXJib3NlID0gRkFMU0UKICApCgojIFNhdmUgdGhlIG1vZGVsIApmaXRfbWxlbkBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfbWxlbiwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfbGVuX2Nvci5yZHMiKSkKCmBgYAoKIyBleWV0ciAmIGxlbmd0aApgYGB7ciwgZXZhbD1GQUxTRX0KZWxlbl9kYXRhID0gbGlzdCh4PWVsZW5fdGVtcCwgTj1ucm93KGVsZW5fdGVtcCkpCgpmaXRfZWxlbiA9IHN0YW4oCiAgZmlsZT0ic3Rhbl9tb2RlbHMvc3RhdHNfY29ycmVsYXRpb25fbGVuX25vcm1hbC5zdGFuIiwgCiAgZGF0YT1lbGVuX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X2VsZW5Ac3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X2VsZW4sIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9sZW5fY29yLnJkcyIpKQpgYGAKCgpgYGB7cn0KcHJpbnQoIlN1cnByaXNhbCIpCnN0YXRzX2Nvcl9kZiA9IHByb3ZvX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJnYXplX2R1cmF0aW9uIikgJT4lIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkKcHJpbnQoY29yLnRlc3Qoc3RhdHNfY29yX2RmJG1vdHJfdmFsdWUsIHN0YXRzX2Nvcl9kZiRzdXJwKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3Qoc3RhdHNfY29yX2RmJGV5ZXRyX3ZhbHVlLCBzdGF0c19jb3JfZGYkc3VycCkkZXN0aW1hdGUpCgojIFZpZXcoc3RhdHNfY29yX2RmKQpzdGF0c19jb3JfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgYyg4LCAxMykpICU+JQogIGdncGxvdChhZXMoeCA9IHZhbHVlKSkgKwogIGdlb21fZGVuc2l0eSgpICsKICBmYWNldF93cmFwKH5tZWFzdXJlLCBzY2FsZXMgPSAiZnJlZSIpICsKICB0aGVtZV9idygpICsKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlNldDEiKQoKbXN1cnBfdGVtcCA8LSBzdGF0c19jb3JfZGZbYygibW90cl92YWx1ZSIsICJzdXJwIildICU+JQogIGRhdGEubWF0cml4KCkKZXN1cnBfdGVtcCA8LSBzdGF0c19jb3JfZGZbYygiZXlldHJfdmFsdWUiLCAic3VycCIpXSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAyKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QobXN1cnBfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIk1vVFIgUlRzIGFuZCBTdXJwcmlzYWwiKQoKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXN1cnBfdGVtcCwgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkV5ZVRSIFJUcyBhbmQgU3VycHJpc2FsIikKYGBgCiMgbW90ciAmIHN1cnByaXNhbApgYGB7ciwgZXZhbD1GQUxTRX0KbXN1cnBfZGF0YSA9IGxpc3QoeD1tc3VycF90ZW1wLCBOPW5yb3cobXN1cnBfdGVtcCkpCgpmaXRfbXN1cnAgPSBzdGFuKAogIGZpbGU9InN0YW5fbW9kZWxzL3N0YXRzX2NvcnJlbGF0aW9uLnN0YW4iLCAKICBkYXRhPW1zdXJwX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTgsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogICMgdmVyYm9zZSA9IEZBTFNFCiAgKQoKIyBTYXZlIHRoZSBtb2RlbCAKZml0X21zdXJwQHN0YW5tb2RlbEBkc28gPC0gbmV3KCJjeHhkc28iKQpzYXZlUkRTKGZpdF9tc3VycCwgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfc3VycF9jb3IucmRzIikpCgpgYGAKCiMgZXlldHIgJiBzdXJwcmlzYWwKYGBge3IsIGV2YWw9RkFMU0V9CmVzdXJwX2RhdGEgPSBsaXN0KHg9ZXN1cnBfdGVtcCwgTj1ucm93KGVzdXJwX3RlbXApKQoKZml0X2VzdXJwID0gc3RhbigKICBmaWxlPSJzdGFuX21vZGVscy9zdGF0c19jb3JyZWxhdGlvbi5zdGFuIiwgCiAgZGF0YT1lc3VycF9kYXRhLCAKICBpdGVyPTQwMDAsIAogIGNoYWlucz00LCAKICBjb3Jlcz04LAogIHNlZWQ9NDQ0LAogICMgY29udHJvbD1saXN0KGFkYXB0X2RlbHRhPTAuOTkpLCAKICAjIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9lc3VycEBzdGFubW9kZWxAZHNvIDwtIG5ldygiY3h4ZHNvIikKc2F2ZVJEUyhmaXRfZXN1cnAsIGZpbGUgPSBwYXN0ZTAoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9zdXJwX2Nvci5yZHMiKSkKCmBgYAoKCmBgYHtyfQpmaXRfbWZyZXEgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9mcmVxX2Nvci5yZHMiKQpmaXRfZWZyZXEgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZnJlcV9jb3IucmRzIikKZml0X21sZW4gPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vbW90cl9sZW5fY29yLnJkcyIpCmZpdF9lbGVuID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2xlbl9jb3IucmRzIikKZml0X21zdXJwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL21vdHJfc3VycF9jb3IucmRzIikKZml0X2VzdXJwID0gcmVhZFJEUygiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX3N1cnBfY29yLnJkcyIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTG9nIEZyZXF1ZW5jeSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9tZnJlcSkKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXllVFIgJiBMb2cgRnJlcXVlbmN5IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VmcmVxKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X21sZW4pCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VsZW4pCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBTdXJwcmlzYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpwcmludChmaXRfbXN1cnApCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgU3VycHJpc2FsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VzdXJwKQoKYGBgCgpgYGB7ciwgZXZhbD1GQUxTRX0KIyBNb1RSICYgTG9nIEZyZXEKc3Rhbl90cmFjZShmaXRfbWZyZXEpCnN0YW5fZGVucyhmaXRfbWZyZXEsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfbWZyZXEpCgojIEV5ZVRSICYgTG9nIEZyZXEKc3Rhbl90cmFjZShmaXRfZWZyZXEpCnN0YW5fZGVucyhmaXRfZWZyZXEsIHNlcGFyYXRlX2NoYWlucyA9IFRSVUUpCnN0YW5fcGxvdChmaXRfZWZyZXEpCgojIE1vVFIgJiBMZW4Kc3Rhbl90cmFjZShmaXRfbWxlbikKc3Rhbl9kZW5zKGZpdF9tbGVuLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21sZW4pCgojIEV5ZVRSICYgTGVuCnN0YW5fdHJhY2UoZml0X2VsZW4pCnN0YW5fZGVucyhmaXRfZWxlbiwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lbGVuKQoKIyBNb1RSICYgU3VycHJpc2FsCnN0YW5fdHJhY2UoZml0X21zdXJwKQpzdGFuX2RlbnMoZml0X21zdXJwLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X21zdXJwKQoKIyBFeWVUUiAmIFN1cnByaXNhbApzdGFuX3RyYWNlKGZpdF9lc3VycCkKc3Rhbl9kZW5zKGZpdF9lc3VycCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lc3VycCkKCmBgYAoKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgTG9nIEZyZXEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fbWZyZXEgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X21mcmVxLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21mcmVxKQpjckkgPSBxdWFudGlsZShyaG9fbWZyZXEsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fbWZyZXEpLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIExvZyBGcmVxIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VmcmVxID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lZnJlcSwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lZnJlcSkKY3JJID0gcXVhbnRpbGUocmhvX2VmcmVxLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VmcmVxKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTW9UUiAmIExlbmd0aCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19tbGVuID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tbGVuLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX21sZW4pCmNySSA9IHF1YW50aWxlKHJob19tbGVuLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21sZW4pLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIExlbmd0aCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lbGVuID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lbGVuLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VsZW4pCmNySSA9IHF1YW50aWxlKHJob19lbGVuLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VsZW4pLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl1cbiIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBNb1RSICYgU3VycHJpc2FsIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX21zdXJwID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9tc3VycCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19tc3VycCkKY3JJID0gcXVhbnRpbGUocmhvX21zdXJwLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX21zdXJwKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRXllVFIgJiBTdXJwcmlzYWwgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQpyaG9fZXN1cnAgPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VzdXJwLCAicmhvIilbWzFdXSkKbWVhbiA9IG1lYW4ocmhvX2VzdXJwKQpjckkgPSBxdWFudGlsZShyaG9fZXN1cnAsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXN1cnApLCBwcm9iPTAuOTUpCmNhdCgiTWVhbjogIiwgbWVhbiwgIlxuSFBEOiBbIiwgaHBkOTlbLCJsb3dlciJdLCAiLCAiLCBocGQ5OVssInVwcGVyIl0sICJdIiwgc2VwPSIiLCAiXG5jckk6IFsiLCBjcklbMV0sICIsICIsIGNySVsyXSwgIl0iKQoKYGBgCgoKCmBgYHtyLGV2YWw9RkFMU0V9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBMb2cgRnJlcXVlbmN5LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptZnJlcV9yYW5kIDwtIGV4dHJhY3QoZml0X21mcmVxLCAieF9yYW5kIilbWzFdXQoKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDgwMCksIHlsaW09YygwLCAxMiksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiTW9UUiB2YWx1ZSIsIHlsYWIgPSAiTG9nIEZyZXF1ZW5jeSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtZnJlcV9yYW5kWywxXSwgbWZyZXFfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKG1mcmVxX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UobWZyZXFfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShtZnJlcV9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTG9nIEZyZXF1ZW5jeS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWZyZXFfcmFuZCA8LSBleHRyYWN0KGZpdF9lZnJlcSwgInhfcmFuZCIpW1sxXV0KCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA1MDApLCB5bGltPWMoMCwgMTIpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTG9nIEZyZXF1ZW5jeSIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlZnJlcV9yYW5kWywxXSwgZWZyZXFfcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKGVmcmVxX3RlbXAsIHBjaD0xNiwgY29sPSJyZWQiKQoKIyBhZGQgZGF0YUVsbGlwc2Ugd2l0aCBjb2xvciAKZGF0YUVsbGlwc2UoZWZyZXFfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlZnJlcV9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIE1vVFIgJiBMZW5ndGggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQptbGVuX3JhbmQgPC0gZXh0cmFjdChmaXRfbWxlbiwgInhfcmFuZCIpW1sxXV0KIyBtbGVuX3JhbmQKCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCA4MDApLCB5bGltPWMoMCwgMjApLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIk1vVFIgdmFsdWUiLCB5bGFiID0gIldvcmQgTGVuZ3RoIiwgbWFpbiA9ICJHYXplIER1cmF0aW9uIikgIyAndHlwZSA9ICJuIicgbWFrZXMgc3VyZSB0aGUgcGxvdCBpcyBibGFuawoKIyBhZGQgcG9pbnRzIGZvciB4X3JhbmQgd2l0aCBjb2xvciAKcG9pbnRzKG1sZW5fcmFuZFssMV0sIG1sZW5fcmFuZFssMl0sIGNvbCA9ICJibGFjayIsIHBjaCA9IDE2KQojIGFkZCBwb2ludHMgZm9yIGdkX3RlbXAgd2l0aCBjb2xvciByZWQKcG9pbnRzKG1sZW5fdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShtbGVuX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobWxlbl9yYW5kLCBsZXZlbHMgPSBjKDAuOTUsIDAuOTkpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJibHVlIikKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEV5ZVRSICYgTGVuZ3RoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWxlbl9yYW5kIDwtIGV4dHJhY3QoZml0X2VsZW4sICJ4X3JhbmQiKVtbMV1dCiMgZWxlbl9yYW5kCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWVUUiB2YWx1ZSIsIHlsYWIgPSAiV29yZCBMZW5ndGgiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWxlbl9yYW5kWywxXSwgZWxlbl9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZWxlbl90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVsZW5fcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlbGVuX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gTW9UUiAmIFN1cnByaXNhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCm1zdXJwX3JhbmQgPC0gZXh0cmFjdChmaXRfbXN1cnAsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJNb1RSIHZhbHVlIiwgeWxhYiA9ICJXb3JkIFN1cnByaXNhbCIsIG1haW4gPSAiR2F6ZSBEdXJhdGlvbiIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhtc3VycF9yYW5kIFssMV0sIG1zdXJwX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhtc3VycF90ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKG1zdXJwX3JhbmQsIGxldmVscyA9IGMoMC41LCAwLjc1KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0ib3JhbmdlIikKZGF0YUVsbGlwc2UobXN1cnBfcmFuZCwgbGV2ZWxzID0gYygwLjk1LCAwLjk5KSwgZmlsbD1ULCBwbG90LnBvaW50cyA9IEYsIGNvbD0iYmx1ZSIpCgpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBFeWVUUiAmIFN1cnByaXNhbCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVzdXJwX3JhbmQgPC0gZXh0cmFjdChmaXRfZXN1cnAsICJ4X3JhbmQiKVtbMV1dCgojIGNyZWF0ZSBhIGJsYW5rIHBsb3QgZmlyc3Qgd2l0aCBhcHByb3ByaWF0ZSBsaW1pdHMKcGxvdCgxLCAxLCB4bGltPWMoMCwgODAwKSwgeWxpbT1jKDAsIDIwKSwgdHlwZT0ibiIsCiAgICAgeGxhYiA9ICJFeWVUUiB2YWx1ZSIsIHlsYWIgPSAiV29yZCBTdXJwcmlzYWwiLCBtYWluID0gIkdhemUgRHVyYXRpb24iKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZXN1cnBfcmFuZCBbLDFdLCBlc3VycF9yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZXN1cnBfdGVtcCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlc3VycF9yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVzdXJwX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCgoKYGBge3J9CnByaW50KCJFeWVUUiB2cy4gRXllVFIgRmlzcnQgUGFzcyBSZWdyZXNzaW9uIFByb2IuIDwgMC4zICIpCgplcmVnX2RmID0gcHJvdm9fZXlldHJfZ3JvdXBlZF9kZiAlPiUgZmlsdGVyKG1ldHJpYyA9PSAiRlBSZWciKSAlPiUgZGlzdGluY3QoKSAlPiUgI2dyb3VwX2J5KHRleHRfaWQsIG1ldHJpYywgbWVhc3VyZSkgJT4lCiAgIyBzdW1tYXJpemUodmFsdWUgPSBtZWFuKHZhbHVlKSkgJT4lCiAgZmlsdGVyKCEocm93X251bWJlcigpICVpbiUgYyg0NDMsIDQ0NCwgNDQ1LCA0NDYpKSkgJT4lCiAgICBzcHJlYWQobWVhc3VyZSwgdmFsdWUpICU+JQogICMgc21vb3RoaW5nLCBpZiBpbmNsdWRlcyAwcwogIG11dGF0ZShleWV0cl92YWx1ZV8xID0gIHBtYXgodmFsdWVfMSwgMWUtNSksCiAgICAgICAgIGV5ZXRyX3ZhbHVlXzIgPSBwbWF4KHZhbHVlXzIsIDFlLTUpKQoKZXJlZ19kZl9sb3cgPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSBkaXN0aW5jdCgpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZV8xIDwgMC4zKQojIFZpZXcoZXJlZ19kZl9sb3cpCgplcmVnX2RmX2hpZ2ggPSBwcm92b19leWV0cl9ncm91cGVkX2RmICU+JSBmaWx0ZXIobWV0cmljID09ICJGUFJlZyIpICU+JSBkaXN0aW5jdCgpICU+JSAjZ3JvdXBfYnkodGV4dF9pZCwgbWV0cmljLCBtZWFzdXJlKSAlPiUKICAjIHN1bW1hcml6ZSh2YWx1ZSA9IG1lYW4odmFsdWUpKSAlPiUKICBmaWx0ZXIoIShyb3dfbnVtYmVyKCkgJWluJSBjKDQ0MywgNDQ0LCA0NDUsIDQ0NikpKSAlPiUKICAgIHNwcmVhZChtZWFzdXJlLCB2YWx1ZSkgJT4lCiAgIyBzbW9vdGhpbmcsIGlmIGluY2x1ZGVzIDBzCiAgbXV0YXRlKGV5ZXRyX3ZhbHVlXzEgPSAgcG1heCh2YWx1ZV8xLCAxZS01KSwKICAgICAgICAgZXlldHJfdmFsdWVfMiA9IHBtYXgodmFsdWVfMiwgMWUtNSkpICU+JQogIGZpbHRlcihleWV0cl92YWx1ZV8xID49IDAuMykKIyBWaWV3KGVyZWdfZGZfaGlnaCkgCgpwcmludChjb3IudGVzdChlcmVnX2RmJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGYkZXlldHJfdmFsdWVfMikkZXN0aW1hdGUpCnByaW50KGNvci50ZXN0KGVyZWdfZGYkZXlldHJfdmFsdWVfMSwgZXJlZ19kZiRleWV0cl92YWx1ZV8yKSRwLnZhbHVlKQpwcmludChjb3IudGVzdChlcmVnX2RmX2xvdyRleWV0cl92YWx1ZV8xLCBlcmVnX2RmX2xvdyRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9sb3ckZXlldHJfdmFsdWVfMSwgZXJlZ19kZl9sb3ckZXlldHJfdmFsdWVfMikkcC52YWx1ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGZfaGlnaCRleWV0cl92YWx1ZV8yKSRlc3RpbWF0ZSkKcHJpbnQoY29yLnRlc3QoZXJlZ19kZl9oaWdoJGV5ZXRyX3ZhbHVlXzEsIGVyZWdfZGZfaGlnaCRleWV0cl92YWx1ZV8yKSRwLnZhbHVlKQoKIyBWaWV3KGVnZF9kZikKCmVyZWdfZGYgJT4lIAogIGdhdGhlcihtZWFzdXJlLCB2YWx1ZSwgNTo2KSAlPiUKICBnZ3Bsb3QoYWVzKHggPSB2YWx1ZSkpICsKICBnZW9tX2RlbnNpdHkoKSArCiAgZmFjZXRfd3JhcCh+bWVhc3VyZSwgc2NhbGVzID0gImZyZWUiKSArCiAgdGhlbWVfYncoKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikKCmVyZWdfdGVtcCA8LSBlcmVnX2RmW2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkcm9wX25hKCkgJT4lCiAgZGF0YS5tYXRyaXgoKQplcmVnX3RlbXBfbG93IDwtIGVyZWdfZGZfbG93W2MoImV5ZXRyX3ZhbHVlXzEiLCAiZXlldHJfdmFsdWVfMiIpXSAlPiUKICBkcm9wX25hKCkgJT4lCiAgZGF0YS5tYXRyaXgoKQplcmVnX3RlbXBfaGlnaCA8LSBlcmVnX2RmX2hpZ2hbYygiZXlldHJfdmFsdWVfMSIsICJleWV0cl92YWx1ZV8yIildICU+JQogIGRyb3BfbmEoKSAlPiUKICBkYXRhLm1hdHJpeCgpCgojIFNldCB1cCB0aGUgcGxvdHRpbmcgYXJlYSB3aXRoIHR3byBzaWRlLWJ5LXNpZGUgcGxvdHMKcGFyKG1mcm93ID0gYygxLCAzKSkKIyBQbG90IHRoZSBmaXJzdCBkYXRhIG1hdHJpeCBnZF90ZW1wCnBsb3QoZXJlZ190ZW1wLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgYWxsIGRhdGEgTm90IExvZy1UcmFuc2Zvcm1lZCIpCnBsb3QoZXJlZ190ZW1wX2xvdywgcGNoID0gMTYsIGNvbCA9ICJibHVlIiwKICAgICBtYWluID0gIkZQUmVnIDwgMC4zIE5vdCBMb2ctVHJhbnNmb3JtZWQiKQpwbG90KGVyZWdfdGVtcF9oaWdoLCBwY2ggPSAxNiwgY29sID0gImJsdWUiLAogICAgIG1haW4gPSAiRlBSZWcgPiAwLjMgTm90IExvZy1UcmFuc2Zvcm1lZCIpCmBgYAoKCmBgYHtyLCBldmFsPUZBTFNFfQojIC0tLS0tLS1maXQgbW9kZWwgZXlldHIgdnMuIGV5ZXRyIEZQUmVnIDwwLjMgJiA+PTAuMyAtLS0tLS0tLS0tCnJlZ19kYXRhID0gbGlzdCh4PWVyZWdfdGVtcCwgTj1ucm93KGVyZWdfdGVtcCkpCmZpdF9yZWcgPSBzdGFuKAogICMgZmlsZT0ic3Rhbl9tb2RlbHMvYml2YXJpYXRlX2JldGFfY29ycmVsYXRpb25fcmVnLnN0YW4iLCAKICBmaWxlID0gInN0YW5fbW9kZWxzL2JpdmFyaWF0ZV9ub3JtYWxfcmVnLnN0YW4iLAogIGRhdGE9cmVnX2RhdGEsIAogIGl0ZXI9NDAwMCwgCiAgY2hhaW5zPTQsIAogIGNvcmVzPTQsCiAgc2VlZD00NDQsCiAgIyBjb250cm9sPWxpc3QoYWRhcHRfZGVsdGE9MC45OSksIAogIHZlcmJvc2UgPSBGQUxTRQogICkKCiMgU2F2ZSB0aGUgbW9kZWwgCmZpdF9yZWdAc3Rhbm1vZGVsQGRzbyA8LSBuZXcoImN4eGRzbyIpCnNhdmVSRFMoZml0X3JlZywgZmlsZSA9IHBhc3RlMCgiLi9iYXllc2lhbl9tb2RlbHMvYmF5ZXNpYW5fbW9kZWxzX2NvcnJlbGF0aW9uL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKSkKYGBgCgoKCiMgZXhwbG9yYXRvcnk6IGRpdmlkZSBleWUgdHJhY2tpbmcgcmVncmVzc2lvbiBkYXRhIGludG8gdHdvIHBhcnRzLgpgYGB7cn0KIyBmaXRfZXJlZ19hbGwgPSByZWFkUkRTKCIuL2V5ZXRyX2V5ZXRyX0ZQUmVnX2Nvcl9hbGxfZGF0YS5yZHMiKQpmaXRfZXJlZ19hbGwgPSByZWFkUkRTKCIuL2JheWVzaWFuX21vZGVscy9iYXllc2lhbl9tb2RlbHNfY29ycmVsYXRpb24vZXlldHJfZXlldHJfRlBSZWdfY29yLnJkcyIpCmZpdF9lcmVnX2xvdyA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfMDAtMDMucmRzIikKZml0X2VyZWdfaGlnaCA9IHJlYWRSRFMoIi4vYmF5ZXNpYW5fbW9kZWxzL2JheWVzaWFuX21vZGVsc19jb3JyZWxhdGlvbi9leWV0cl9leWV0cl9GUFJlZ19jb3JfMDMtMS5yZHMiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIFByb2IuIGFsbCBkYXRhIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWdfYWxsKQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi48IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcHJpbnQoZml0X2VyZWdfbG93KQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gUHJvYi4+PSAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnByaW50KGZpdF9lcmVnX2hpZ2gpCgpgYGAKCgpgYGB7cn0KIyAjIEZQUmVnIGFsbCBkYXRhCnN0YW5fdHJhY2UoZml0X2VyZWdfYWxsKQpzdGFuX2RlbnMoZml0X2VyZWdfYWxsLCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWdfYWxsKQoKIyAjIEZQUmVnIDwgMC4zCnN0YW5fdHJhY2UoZml0X2VyZWdfbG93KQpzdGFuX2RlbnMoZml0X2VyZWdfbG93LCBzZXBhcmF0ZV9jaGFpbnMgPSBUUlVFKQpzdGFuX3Bsb3QoZml0X2VyZWdfbG93KQoKIyBGUFJlZyA+PSAwLjMKc3Rhbl90cmFjZShmaXRfZXJlZ19oaWdoKQpzdGFuX2RlbnMoZml0X2VyZWdfaGlnaCwgc2VwYXJhdGVfY2hhaW5zID0gVFJVRSkKc3Rhbl9wbG90KGZpdF9lcmVnX2hpZ2gpCmBgYAoKYGBge3J9CnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiBhbGwgZGF0YS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWdfYWxsID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnX2FsbCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2FsbCkKY3JJID0gcXVhbnRpbGUocmhvX2VyZWdfYWxsLCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWdfYWxsKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA8IDAuMy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKcmhvX2VyZWdfbG93ID0gYXMubnVtZXJpYyhleHRyYWN0KGZpdF9lcmVnX2xvdywgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2xvdykKY3JJID0gcXVhbnRpbGUocmhvX2VyZWdfbG93LCBjKC4wMjUsIC45NzUpKQpocGQ5OSA9IEhQRGludGVydmFsKGFzLm1jbWMocmhvX2VyZWdfbG93KSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQoKCnByaW50KCctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIEZpcnN0IFBhc3MgUmVncmVzc2lvbiA+PSAwLjMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCnJob19lcmVnX2hpZ2ggPSBhcy5udW1lcmljKGV4dHJhY3QoZml0X2VyZWdfaGlnaCwgInJobyIpW1sxXV0pCm1lYW4gPSBtZWFuKHJob19lcmVnX2hpZ2gpCmNySSA9IHF1YW50aWxlKHJob19lcmVnX2hpZ2gsIGMoLjAyNSwgLjk3NSkpCmhwZDk5ID0gSFBEaW50ZXJ2YWwoYXMubWNtYyhyaG9fZXJlZ19oaWdoKSwgcHJvYj0wLjk1KQpjYXQoIk1lYW46ICIsIG1lYW4sICJcbkhQRDogWyIsIGhwZDk5WywibG93ZXIiXSwgIiwgIiwgaHBkOTlbLCJ1cHBlciJdLCAiXSIsIHNlcD0iIiwgIlxuY3JJOiBbIiwgY3JJWzFdLCAiLCAiLCBjcklbMl0sICJdXG4iKQpgYGAKCmBgYHtyfQpwcmludCgnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBGaXJzdCBQYXNzIFJlZ3Jlc3Npb24gYWxsIGRhdGEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nKQplYWxscmVnX3JhbmQgPC0gZXh0cmFjdChmaXRfZXJlZ19hbGwsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWFsbHJlZ19yYW5kWywxXSwgZWFsbHJlZ19yYW5kWywyXSwgY29sID0gImJsYWNrIiwgcGNoID0gMTYpCiMgYWRkIHBvaW50cyBmb3IgZ2RfdGVtcCB3aXRoIGNvbG9yIHJlZApwb2ludHMoZXJlZ190ZW1wLCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVhbGxyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlYWxscmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uIDwgMC4zIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tJykKZWxvd3JlZ19yYW5kIDwtIGV4dHJhY3QoZml0X2VyZWdfbG93LCAieF9yYW5kIilbWzFdXQojIHByaW50KGVsb3dyZWdfcmFuZCkKIyBjcmVhdGUgYSBibGFuayBwbG90IGZpcnN0IHdpdGggYXBwcm9wcmlhdGUgbGltaXRzCnBsb3QoMSwgMSwgeGxpbT1jKDAsIDEpLCB5bGltPWMoMCwgMSksIHR5cGU9Im4iLAogICAgIHhsYWIgPSAiRXllIHRyYWNraW5nIHZhbHVlIiwgeWxhYiA9ICJNb1RSIHZhbHVlIiwgbWFpbiA9ICJGUFJlZyIpICMgJ3R5cGUgPSAibiInIG1ha2VzIHN1cmUgdGhlIHBsb3QgaXMgYmxhbmsKCiMgYWRkIHBvaW50cyBmb3IgeF9yYW5kIHdpdGggY29sb3IgCnBvaW50cyhlbG93cmVnX3JhbmRbLDFdLCBlbG93cmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlcmVnX3RlbXBfbG93LCBwY2g9MTYsIGNvbD0icmVkIikKCiMgYWRkIGRhdGFFbGxpcHNlIHdpdGggY29sb3IgCmRhdGFFbGxpcHNlKGVsb3dyZWdfcmFuZCwgbGV2ZWxzID0gYygwLjUsIDAuNzUpLCBmaWxsPVQsIHBsb3QucG9pbnRzID0gRiwgY29sPSJvcmFuZ2UiKQpkYXRhRWxsaXBzZShlbG93cmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKcHJpbnQoJy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gRmlyc3QgUGFzcyBSZWdyZXNzaW9uID49IDAuMyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScpCmVoaWdocmVnX3JhbmRfc2FtcGxlcyA8LSBleHRyYWN0KGZpdF9lcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgcHJpbnQobWhpZ2hyZWdfcmFuZF9zYW1wbGVzKQpzZWxlY3RlZF9pbmRpY2VzIDwtIHNhbXBsZSgxOm5yb3coZWhpZ2hyZWdfcmFuZF9zYW1wbGVzKSwgOTAwKQplaGlnaHJlZ19yYW5kIDwtIGVoaWdocmVnX3JhbmRfc2FtcGxlc1tzZWxlY3RlZF9pbmRpY2VzLCBdCiMgbWhpZ2hyZWdfcmFuZCA8LSBleHRyYWN0KGZpdF9tcmVnX2hpZ2gsICJ4X3JhbmQiKVtbMV1dCiMgY3JlYXRlIGEgYmxhbmsgcGxvdCBmaXJzdCB3aXRoIGFwcHJvcHJpYXRlIGxpbWl0cwpwbG90KDEsIDEsIHhsaW09YygwLCAxKSwgeWxpbT1jKDAsIDEpLCB0eXBlPSJuIiwKICAgICB4bGFiID0gIkV5ZSB0cmFja2luZyB2YWx1ZSIsIHlsYWIgPSAiTW9UUiB2YWx1ZSIsIG1haW4gPSAiRlBSZWciKSAjICd0eXBlID0gIm4iJyBtYWtlcyBzdXJlIHRoZSBwbG90IGlzIGJsYW5rCgojIGFkZCBwb2ludHMgZm9yIHhfcmFuZCB3aXRoIGNvbG9yIApwb2ludHMoZWhpZ2hyZWdfcmFuZFssMV0sIGVoaWdocmVnX3JhbmRbLDJdLCBjb2wgPSAiYmxhY2siLCBwY2ggPSAxNikKIyBhZGQgcG9pbnRzIGZvciBnZF90ZW1wIHdpdGggY29sb3IgcmVkCnBvaW50cyhlcmVnX3RlbXBfaGlnaCwgcGNoPTE2LCBjb2w9InJlZCIpCgojIGFkZCBkYXRhRWxsaXBzZSB3aXRoIGNvbG9yIApkYXRhRWxsaXBzZShlaGlnaHJlZ19yYW5kLCBsZXZlbHMgPSBjKDAuNSwgMC43NSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9Im9yYW5nZSIpCmRhdGFFbGxpcHNlKGVoaWdocmVnX3JhbmQsIGxldmVscyA9IGMoMC45NSwgMC45OSksIGZpbGw9VCwgcGxvdC5wb2ludHMgPSBGLCBjb2w9ImJsdWUiKQoKYGBgCg==